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/pref_registry/pref_registry_syncable.h"
18 #include "sync/api/attachments/attachment_id.h"
19 #include "sync/api/sync_change.h"
20 #include "sync/api/sync_data.h"
21 #include "sync/api/sync_error_factory_mock.h"
22 #include "sync/api/syncable_service.h"
23 #include "sync/internal_api/public/attachments/attachment_service_proxy_for_test.h"
24 #include "sync/protocol/preference_specifics.pb.h"
25 #include "sync/protocol/sync.pb.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27 #include "ui/base/l10n/l10n_util.h"
29 using syncer::SyncChange
;
30 using syncer::SyncData
;
33 const char kExampleUrl0
[] = "http://example.com/0";
34 const char kExampleUrl1
[] = "http://example.com/1";
35 const char kExampleUrl2
[] = "http://example.com/2";
36 const char kUnsyncedPreferenceName
[] = "nonsense_pref_name";
37 const char kUnsyncedPreferenceDefaultValue
[] = "default";
38 const char kNonDefaultCharsetValue
[] = "foo";
41 class TestSyncProcessorStub
: public syncer::SyncChangeProcessor
{
43 explicit TestSyncProcessorStub(syncer::SyncChangeList
* output
)
44 : output_(output
), fail_next_(false) {}
45 syncer::SyncError
ProcessSyncChanges(
46 const tracked_objects::Location
& from_here
,
47 const syncer::SyncChangeList
& change_list
) override
{
49 output_
->insert(output_
->end(), change_list
.begin(), change_list
.end());
52 return syncer::SyncError(
53 FROM_HERE
, syncer::SyncError::DATATYPE_ERROR
, "Error",
56 return syncer::SyncError();
59 void FailNextProcessSyncChanges() {
63 syncer::SyncDataList
GetAllSyncData(syncer::ModelType type
) const override
{
64 return syncer::SyncDataList();
67 syncer::SyncChangeList
* output_
;
71 class PrefServiceSyncableTest
: public testing::Test
{
73 PrefServiceSyncableTest()
74 : pref_sync_service_(NULL
),
75 test_processor_(NULL
),
76 next_pref_remote_sync_node_id_(0) {}
78 void SetUp() override
{
79 prefs_
.registry()->RegisterStringPref(kUnsyncedPreferenceName
,
80 kUnsyncedPreferenceDefaultValue
);
81 prefs_
.registry()->RegisterStringPref(
84 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
85 prefs_
.registry()->RegisterListPref(
86 prefs::kURLsToRestoreOnStartup
,
87 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
88 prefs_
.registry()->RegisterListPref(prefs::kURLsToRestoreOnStartupOld
);
89 prefs_
.registry()->RegisterStringPref(
90 prefs::kDefaultCharset
,
91 l10n_util::GetStringUTF8(IDS_DEFAULT_ENCODING
),
92 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
94 pref_sync_service_
= reinterpret_cast<PrefModelAssociator
*>(
95 prefs_
.GetSyncableService(syncer::PREFERENCES
));
96 ASSERT_TRUE(pref_sync_service_
);
97 next_pref_remote_sync_node_id_
= 0;
100 syncer::SyncChange
MakeRemoteChange(
102 const std::string
& name
,
103 const base::Value
& value
,
104 SyncChange::SyncChangeType type
) {
105 std::string serialized
;
106 JSONStringValueSerializer
json(&serialized
);
107 if (!json
.Serialize(value
))
108 return syncer::SyncChange();
109 sync_pb::EntitySpecifics entity
;
110 sync_pb::PreferenceSpecifics
* pref_one
= entity
.mutable_preference();
111 pref_one
->set_name(name
);
112 pref_one
->set_value(serialized
);
113 return syncer::SyncChange(
116 syncer::SyncData::CreateRemoteData(
120 syncer::AttachmentIdList(),
121 syncer::AttachmentServiceProxyForTest::Create()));
124 void AddToRemoteDataList(const std::string
& name
,
125 const base::Value
& value
,
126 syncer::SyncDataList
* out
) {
127 std::string serialized
;
128 JSONStringValueSerializer
json(&serialized
);
129 ASSERT_TRUE(json
.Serialize(value
));
130 sync_pb::EntitySpecifics one
;
131 sync_pb::PreferenceSpecifics
* pref_one
= one
.mutable_preference();
132 pref_one
->set_name(name
);
133 pref_one
->set_value(serialized
);
134 out
->push_back(SyncData::CreateRemoteData(
135 ++next_pref_remote_sync_node_id_
,
138 syncer::AttachmentIdList(),
139 syncer::AttachmentServiceProxyForTest::Create()));
142 void InitWithSyncDataTakeOutput(const syncer::SyncDataList
& initial_data
,
143 syncer::SyncChangeList
* output
) {
144 test_processor_
= new TestSyncProcessorStub(output
);
145 syncer::SyncMergeResult r
= pref_sync_service_
->MergeDataAndStartSyncing(
146 syncer::PREFERENCES
, initial_data
,
147 scoped_ptr
<syncer::SyncChangeProcessor
>(test_processor_
),
148 scoped_ptr
<syncer::SyncErrorFactory
>(
149 new syncer::SyncErrorFactoryMock()));
150 EXPECT_FALSE(r
.error().IsSet());
153 void InitWithNoSyncData() {
154 InitWithSyncDataTakeOutput(syncer::SyncDataList(), NULL
);
157 const base::Value
& GetPreferenceValue(const std::string
& name
) {
158 const PrefService::Preference
* preference
=
159 prefs_
.FindPreference(name
.c_str());
160 return *preference
->GetValue();
163 scoped_ptr
<base::Value
> FindValue(const std::string
& name
,
164 const syncer::SyncChangeList
& list
) {
165 syncer::SyncChangeList::const_iterator it
= list
.begin();
166 for (; it
!= list
.end(); ++it
) {
167 if (syncer::SyncDataLocal(it
->sync_data()).GetTag() == name
) {
168 return make_scoped_ptr(base::JSONReader::DeprecatedRead(
169 it
->sync_data().GetSpecifics().preference().value()));
172 return scoped_ptr
<base::Value
>();
175 bool IsSynced(const std::string
& pref_name
) {
176 return pref_sync_service_
->registered_preferences().count(pref_name
) > 0;
179 bool HasSyncData(const std::string
& pref_name
) {
180 return pref_sync_service_
->IsPrefSynced(pref_name
);
183 // Returns whether a given preference name is a new name of a migrated
184 // preference. Exposed here for testing.
185 static bool IsMigratedPreference(const char* preference_name
) {
186 return PrefModelAssociator::IsMigratedPreference(preference_name
);
188 static bool IsOldMigratedPreference(const char* old_preference_name
) {
189 return PrefModelAssociator::IsOldMigratedPreference(old_preference_name
);
192 PrefService
* GetPrefs() { return &prefs_
; }
193 TestingPrefServiceSyncable
* GetTestingPrefService() { return &prefs_
; }
196 TestingPrefServiceSyncable prefs_
;
198 PrefModelAssociator
* pref_sync_service_
;
199 TestSyncProcessorStub
* test_processor_
;
201 // TODO(tim): Remove this by fixing AttachmentServiceProxyForTest.
202 base::MessageLoop loop_
;
204 int next_pref_remote_sync_node_id_
;
207 TEST_F(PrefServiceSyncableTest
, CreatePrefSyncData
) {
208 prefs_
.SetString(prefs::kHomePage
, kExampleUrl0
);
210 const PrefService::Preference
* pref
=
211 prefs_
.FindPreference(prefs::kHomePage
);
212 syncer::SyncData sync_data
;
213 EXPECT_TRUE(pref_sync_service_
->CreatePrefSyncData(pref
->name(),
214 *pref
->GetValue(), &sync_data
));
215 EXPECT_EQ(std::string(prefs::kHomePage
),
216 syncer::SyncDataLocal(sync_data
).GetTag());
217 const sync_pb::PreferenceSpecifics
& specifics(sync_data
.GetSpecifics().
219 EXPECT_EQ(std::string(prefs::kHomePage
), specifics
.name());
221 scoped_ptr
<base::Value
> value
= base::JSONReader::Read(specifics
.value());
222 EXPECT_TRUE(pref
->GetValue()->Equals(value
.get()));
225 TEST_F(PrefServiceSyncableTest
, ModelAssociationDoNotSyncDefaults
) {
226 const PrefService::Preference
* pref
=
227 prefs_
.FindPreference(prefs::kHomePage
);
228 EXPECT_TRUE(pref
->IsDefaultValue());
229 syncer::SyncChangeList out
;
230 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out
);
232 EXPECT_TRUE(IsSynced(prefs::kHomePage
));
233 EXPECT_TRUE(pref
->IsDefaultValue());
234 EXPECT_FALSE(FindValue(prefs::kHomePage
, out
).get());
237 TEST_F(PrefServiceSyncableTest
, ModelAssociationEmptyCloud
) {
238 prefs_
.SetString(prefs::kHomePage
, kExampleUrl0
);
240 ListPrefUpdate
update(GetPrefs(), prefs::kURLsToRestoreOnStartup
);
241 base::ListValue
* url_list
= update
.Get();
242 url_list
->Append(new base::StringValue(kExampleUrl0
));
243 url_list
->Append(new base::StringValue(kExampleUrl1
));
245 syncer::SyncChangeList out
;
246 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out
);
248 scoped_ptr
<base::Value
> value(FindValue(prefs::kHomePage
, out
));
249 ASSERT_TRUE(value
.get());
250 EXPECT_TRUE(GetPreferenceValue(prefs::kHomePage
).Equals(value
.get()));
251 value
= FindValue(prefs::kURLsToRestoreOnStartup
, out
).Pass();
252 ASSERT_TRUE(value
.get());
254 GetPreferenceValue(prefs::kURLsToRestoreOnStartup
).Equals(value
.get()));
257 TEST_F(PrefServiceSyncableTest
, ModelAssociationCloudHasData
) {
258 prefs_
.SetString(prefs::kHomePage
, kExampleUrl0
);
260 ListPrefUpdate
update(GetPrefs(), prefs::kURLsToRestoreOnStartup
);
261 base::ListValue
* url_list
= update
.Get();
262 url_list
->Append(new base::StringValue(kExampleUrl0
));
263 url_list
->Append(new base::StringValue(kExampleUrl1
));
266 syncer::SyncDataList in
;
267 syncer::SyncChangeList out
;
268 AddToRemoteDataList(prefs::kHomePage
, base::StringValue(kExampleUrl1
), &in
);
269 base::ListValue urls_to_restore
;
270 urls_to_restore
.Append(new base::StringValue(kExampleUrl1
));
271 urls_to_restore
.Append(new base::StringValue(kExampleUrl2
));
272 AddToRemoteDataList(prefs::kURLsToRestoreOnStartup
, urls_to_restore
, &in
);
273 AddToRemoteDataList(prefs::kDefaultCharset
,
274 base::StringValue(kNonDefaultCharsetValue
),
276 InitWithSyncDataTakeOutput(in
, &out
);
278 ASSERT_FALSE(FindValue(prefs::kHomePage
, out
).get());
279 ASSERT_FALSE(FindValue(prefs::kDefaultCharset
, out
).get());
281 EXPECT_EQ(kExampleUrl1
, prefs_
.GetString(prefs::kHomePage
));
283 scoped_ptr
<base::ListValue
> expected_urls(new base::ListValue
);
284 expected_urls
->Append(new base::StringValue(kExampleUrl1
));
285 expected_urls
->Append(new base::StringValue(kExampleUrl2
));
286 expected_urls
->Append(new base::StringValue(kExampleUrl0
));
287 scoped_ptr
<base::Value
> value(
288 FindValue(prefs::kURLsToRestoreOnStartup
, out
));
289 ASSERT_TRUE(value
.get());
290 EXPECT_TRUE(value
->Equals(expected_urls
.get()));
291 EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartup
).
292 Equals(expected_urls
.get()));
293 EXPECT_EQ(kNonDefaultCharsetValue
,
294 prefs_
.GetString(prefs::kDefaultCharset
));
297 TEST_F(PrefServiceSyncableTest
, ModelAssociationMigrateOldData
) {
298 ASSERT_TRUE(IsMigratedPreference(prefs::kURLsToRestoreOnStartup
));
299 ASSERT_TRUE(IsOldMigratedPreference(prefs::kURLsToRestoreOnStartupOld
));
301 syncer::SyncDataList in
;
302 syncer::SyncChangeList out
;
303 base::ListValue urls_to_restore
;
304 urls_to_restore
.Append(new base::StringValue(kExampleUrl1
));
305 urls_to_restore
.Append(new base::StringValue(kExampleUrl2
));
306 AddToRemoteDataList(prefs::kURLsToRestoreOnStartupOld
, urls_to_restore
,
308 InitWithSyncDataTakeOutput(in
, &out
);
310 // Expect that the new preference data contains the old pref's values.
311 scoped_ptr
<base::ListValue
> expected_urls(new base::ListValue
);
312 expected_urls
->Append(new base::StringValue(kExampleUrl1
));
313 expected_urls
->Append(new base::StringValue(kExampleUrl2
));
315 ASSERT_TRUE(HasSyncData(prefs::kURLsToRestoreOnStartup
));
316 scoped_ptr
<base::Value
> value(
317 FindValue(prefs::kURLsToRestoreOnStartup
, out
));
318 ASSERT_TRUE(value
.get());
319 EXPECT_TRUE(value
->Equals(expected_urls
.get()));
320 EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartup
).
321 Equals(expected_urls
.get()));
323 // The old preference value should be the same.
324 expected_urls
.reset(new base::ListValue
);
325 ASSERT_FALSE(FindValue(prefs::kURLsToRestoreOnStartupOld
, out
).get());
326 EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartupOld
).
327 Equals(expected_urls
.get()));
330 TEST_F(PrefServiceSyncableTest
, ModelAssociationCloudHasOldMigratedData
) {
331 ASSERT_TRUE(IsMigratedPreference(prefs::kURLsToRestoreOnStartup
));
332 ASSERT_TRUE(IsOldMigratedPreference(prefs::kURLsToRestoreOnStartupOld
));
333 prefs_
.SetString(prefs::kHomePage
, kExampleUrl0
);
335 ListPrefUpdate
update(GetPrefs(), prefs::kURLsToRestoreOnStartup
);
336 base::ListValue
* url_list
= update
.Get();
337 url_list
->Append(new base::StringValue(kExampleUrl0
));
338 url_list
->Append(new base::StringValue(kExampleUrl1
));
341 syncer::SyncDataList in
;
342 syncer::SyncChangeList out
;
343 base::ListValue urls_to_restore
;
344 urls_to_restore
.Append(new base::StringValue(kExampleUrl1
));
345 urls_to_restore
.Append(new base::StringValue(kExampleUrl2
));
346 AddToRemoteDataList(prefs::kURLsToRestoreOnStartupOld
, urls_to_restore
, &in
);
347 AddToRemoteDataList(prefs::kHomePage
, base::StringValue(kExampleUrl1
), &in
);
348 InitWithSyncDataTakeOutput(in
, &out
);
350 ASSERT_FALSE(FindValue(prefs::kHomePage
, out
).get());
352 // Expect that the new preference data contains the merged old prefs values.
353 scoped_ptr
<base::ListValue
> expected_urls(new base::ListValue
);
354 expected_urls
->Append(new base::StringValue(kExampleUrl1
));
355 expected_urls
->Append(new base::StringValue(kExampleUrl2
));
356 expected_urls
->Append(new base::StringValue(kExampleUrl0
));
358 ASSERT_TRUE(HasSyncData(prefs::kURLsToRestoreOnStartup
));
359 scoped_ptr
<base::Value
> value(
360 FindValue(prefs::kURLsToRestoreOnStartup
, out
));
361 ASSERT_TRUE(value
.get());
362 EXPECT_TRUE(value
->Equals(expected_urls
.get()));
363 EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartup
).
364 Equals(expected_urls
.get()));
366 expected_urls
.reset(new base::ListValue
);
367 value
= FindValue(prefs::kURLsToRestoreOnStartupOld
, out
).Pass();
368 ASSERT_TRUE(value
.get());
369 EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartupOld
).
370 Equals(expected_urls
.get()));
373 TEST_F(PrefServiceSyncableTest
, ModelAssociationCloudHasNewMigratedData
) {
374 ASSERT_TRUE(IsMigratedPreference(prefs::kURLsToRestoreOnStartup
));
375 ASSERT_TRUE(IsOldMigratedPreference(prefs::kURLsToRestoreOnStartupOld
));
376 prefs_
.SetString(prefs::kHomePage
, kExampleUrl0
);
378 ListPrefUpdate
update(GetPrefs(), prefs::kURLsToRestoreOnStartupOld
);
379 base::ListValue
* url_list
= update
.Get();
380 url_list
->Append(new base::StringValue(kExampleUrl0
));
381 url_list
->Append(new base::StringValue(kExampleUrl1
));
384 syncer::SyncDataList in
;
385 syncer::SyncChangeList out
;
386 base::ListValue urls_to_restore
;
387 urls_to_restore
.Append(new base::StringValue(kExampleUrl1
));
388 urls_to_restore
.Append(new base::StringValue(kExampleUrl2
));
389 AddToRemoteDataList(prefs::kURLsToRestoreOnStartupOld
, urls_to_restore
, &in
);
390 AddToRemoteDataList(prefs::kHomePage
, base::StringValue(kExampleUrl1
), &in
);
391 InitWithSyncDataTakeOutput(in
, &out
);
393 scoped_ptr
<base::Value
> value(FindValue(prefs::kHomePage
, out
));
394 ASSERT_FALSE(value
.get());
396 // Expect that the cloud data under the new migrated preference name sticks.
397 scoped_ptr
<base::ListValue
> expected_urls(new base::ListValue
);
398 expected_urls
->Append(new base::StringValue(kExampleUrl1
));
399 expected_urls
->Append(new base::StringValue(kExampleUrl2
));
401 ASSERT_TRUE(HasSyncData(prefs::kURLsToRestoreOnStartup
));
402 value
= FindValue(prefs::kURLsToRestoreOnStartup
, out
).Pass();
403 ASSERT_TRUE(value
.get());
404 EXPECT_TRUE(value
->Equals(expected_urls
.get()));
405 EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartup
).
406 Equals(expected_urls
.get()));
408 // The old preference data should still be here, though not synced.
409 expected_urls
.reset(new base::ListValue
);
410 expected_urls
->Append(new base::StringValue(kExampleUrl0
));
411 expected_urls
->Append(new base::StringValue(kExampleUrl1
));
413 value
= FindValue(prefs::kURLsToRestoreOnStartupOld
, out
).Pass();
414 ASSERT_FALSE(value
.get());
415 EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartupOld
).
416 Equals(expected_urls
.get()));
419 TEST_F(PrefServiceSyncableTest
,
420 ModelAssociationCloudAddsOldAndNewMigratedData
) {
421 ASSERT_TRUE(IsMigratedPreference(prefs::kURLsToRestoreOnStartup
));
422 ASSERT_TRUE(IsOldMigratedPreference(prefs::kURLsToRestoreOnStartupOld
));
423 prefs_
.SetString(prefs::kHomePage
, kExampleUrl0
);
425 ListPrefUpdate
update_old(GetPrefs(), prefs::kURLsToRestoreOnStartupOld
);
426 base::ListValue
* url_list_old
= update_old
.Get();
427 url_list_old
->Append(new base::StringValue(kExampleUrl0
));
428 url_list_old
->Append(new base::StringValue(kExampleUrl1
));
429 ListPrefUpdate
update(GetPrefs(), prefs::kURLsToRestoreOnStartup
);
430 base::ListValue
* url_list
= update
.Get();
431 url_list
->Append(new base::StringValue(kExampleUrl1
));
432 url_list
->Append(new base::StringValue(kExampleUrl2
));
435 syncer::SyncDataList in
;
436 syncer::SyncChangeList out
;
437 AddToRemoteDataList(prefs::kHomePage
, base::StringValue(kExampleUrl1
), &in
);
438 InitWithSyncDataTakeOutput(in
, &out
);
440 scoped_ptr
<base::Value
> value(FindValue(prefs::kHomePage
, out
));
441 ASSERT_FALSE(value
.get());
443 // Expect that the cloud data under the new migrated preference name sticks.
444 scoped_ptr
<base::ListValue
> expected_urls(new base::ListValue
);
445 expected_urls
->Append(new base::StringValue(kExampleUrl1
));
446 expected_urls
->Append(new base::StringValue(kExampleUrl2
));
448 ASSERT_TRUE(HasSyncData(prefs::kURLsToRestoreOnStartup
));
449 value
= FindValue(prefs::kURLsToRestoreOnStartup
, out
).Pass();
450 ASSERT_TRUE(value
.get());
451 EXPECT_TRUE(value
->Equals(expected_urls
.get()));
452 EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartup
).
453 Equals(expected_urls
.get()));
455 // Should not have synced in the old startup url values.
456 value
= FindValue(prefs::kURLsToRestoreOnStartupOld
, out
).Pass();
457 ASSERT_FALSE(value
.get());
458 EXPECT_FALSE(GetPreferenceValue(prefs::kURLsToRestoreOnStartupOld
).
459 Equals(expected_urls
.get()));
462 TEST_F(PrefServiceSyncableTest
, FailModelAssociation
) {
463 syncer::SyncChangeList output
;
464 TestSyncProcessorStub
* stub
= new TestSyncProcessorStub(&output
);
465 stub
->FailNextProcessSyncChanges();
466 syncer::SyncMergeResult r
= pref_sync_service_
->MergeDataAndStartSyncing(
467 syncer::PREFERENCES
, syncer::SyncDataList(),
468 scoped_ptr
<syncer::SyncChangeProcessor
>(stub
),
469 scoped_ptr
<syncer::SyncErrorFactory
>(
470 new syncer::SyncErrorFactoryMock()));
471 EXPECT_TRUE(r
.error().IsSet());
474 TEST_F(PrefServiceSyncableTest
, UpdatedPreferenceWithDefaultValue
) {
475 const PrefService::Preference
* pref
=
476 prefs_
.FindPreference(prefs::kHomePage
);
477 EXPECT_TRUE(pref
->IsDefaultValue());
479 syncer::SyncChangeList out
;
480 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out
);
483 base::StringValue
expected(kExampleUrl0
);
484 GetPrefs()->Set(prefs::kHomePage
, expected
);
486 scoped_ptr
<base::Value
> actual(FindValue(prefs::kHomePage
, out
));
487 ASSERT_TRUE(actual
.get());
488 EXPECT_TRUE(expected
.Equals(actual
.get()));
491 TEST_F(PrefServiceSyncableTest
, UpdatedPreferenceWithValue
) {
492 GetPrefs()->SetString(prefs::kHomePage
, kExampleUrl0
);
493 syncer::SyncChangeList out
;
494 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out
);
497 base::StringValue
expected(kExampleUrl1
);
498 GetPrefs()->Set(prefs::kHomePage
, expected
);
500 scoped_ptr
<base::Value
> actual(FindValue(prefs::kHomePage
, out
));
501 ASSERT_TRUE(actual
.get());
502 EXPECT_TRUE(expected
.Equals(actual
.get()));
505 TEST_F(PrefServiceSyncableTest
, UpdatedSyncNodeActionUpdate
) {
506 GetPrefs()->SetString(prefs::kHomePage
, kExampleUrl0
);
507 InitWithNoSyncData();
509 base::StringValue
expected(kExampleUrl1
);
510 syncer::SyncChangeList list
;
511 list
.push_back(MakeRemoteChange(
512 1, prefs::kHomePage
, expected
, SyncChange::ACTION_UPDATE
));
513 pref_sync_service_
->ProcessSyncChanges(FROM_HERE
, list
);
515 const base::Value
& actual
= GetPreferenceValue(prefs::kHomePage
);
516 EXPECT_TRUE(expected
.Equals(&actual
));
519 TEST_F(PrefServiceSyncableTest
, UpdatedSyncNodeActionAdd
) {
520 InitWithNoSyncData();
522 base::StringValue
expected(kExampleUrl0
);
523 syncer::SyncChangeList list
;
524 list
.push_back(MakeRemoteChange(
525 1, prefs::kHomePage
, expected
, SyncChange::ACTION_ADD
));
526 pref_sync_service_
->ProcessSyncChanges(FROM_HERE
, list
);
528 const base::Value
& actual
= GetPreferenceValue(prefs::kHomePage
);
529 EXPECT_TRUE(expected
.Equals(&actual
));
531 pref_sync_service_
->registered_preferences().count(prefs::kHomePage
));
534 TEST_F(PrefServiceSyncableTest
, UpdatedSyncNodeUnknownPreference
) {
535 InitWithNoSyncData();
536 syncer::SyncChangeList list
;
537 base::StringValue
expected(kExampleUrl0
);
538 list
.push_back(MakeRemoteChange(
539 1, "unknown preference", expected
, SyncChange::ACTION_UPDATE
));
540 pref_sync_service_
->ProcessSyncChanges(FROM_HERE
, list
);
541 // Nothing interesting happens on the client when it gets an update
542 // of an unknown preference. We just should not crash.
545 TEST_F(PrefServiceSyncableTest
, ManagedPreferences
) {
546 // Make the homepage preference managed.
547 base::StringValue
managed_value("http://example.com");
548 prefs_
.SetManagedPref(prefs::kHomePage
, managed_value
.DeepCopy());
550 syncer::SyncChangeList out
;
551 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out
);
554 // Changing the homepage preference should not sync anything.
555 base::StringValue
user_value("http://chromium..com");
556 prefs_
.SetUserPref(prefs::kHomePage
, user_value
.DeepCopy());
557 EXPECT_TRUE(out
.empty());
559 // An incoming sync transaction should change the user value, not the managed
561 base::StringValue
sync_value("http://crbug.com");
562 syncer::SyncChangeList list
;
563 list
.push_back(MakeRemoteChange(
564 1, prefs::kHomePage
, sync_value
, SyncChange::ACTION_UPDATE
));
565 pref_sync_service_
->ProcessSyncChanges(FROM_HERE
, list
);
567 EXPECT_TRUE(managed_value
.Equals(prefs_
.GetManagedPref(prefs::kHomePage
)));
568 EXPECT_TRUE(sync_value
.Equals(prefs_
.GetUserPref(prefs::kHomePage
)));
571 // List preferences have special handling at association time due to our ability
572 // to merge the local and sync value. Make sure the merge logic doesn't merge
573 // managed preferences.
574 TEST_F(PrefServiceSyncableTest
, ManagedListPreferences
) {
575 // Make the list of urls to restore on startup managed.
576 base::ListValue managed_value
;
577 managed_value
.Append(new base::StringValue(kExampleUrl0
));
578 managed_value
.Append(new base::StringValue(kExampleUrl1
));
579 prefs_
.SetManagedPref(prefs::kURLsToRestoreOnStartup
,
580 managed_value
.DeepCopy());
582 // Set a cloud version.
583 syncer::SyncDataList in
;
584 syncer::SyncChangeList out
;
585 base::ListValue urls_to_restore
;
586 urls_to_restore
.Append(new base::StringValue(kExampleUrl1
));
587 urls_to_restore
.Append(new base::StringValue(kExampleUrl2
));
588 AddToRemoteDataList(prefs::kURLsToRestoreOnStartup
, urls_to_restore
, &in
);
590 // Start sync and verify the synced value didn't get merged.
591 InitWithSyncDataTakeOutput(in
, &out
);
592 EXPECT_FALSE(FindValue(prefs::kURLsToRestoreOnStartup
, out
).get());
595 // Changing the user's urls to restore on startup pref should not sync
597 base::ListValue user_value
;
598 user_value
.Append(new base::StringValue("http://chromium.org"));
599 prefs_
.SetUserPref(prefs::kURLsToRestoreOnStartup
, user_value
.DeepCopy());
600 EXPECT_FALSE(FindValue(prefs::kURLsToRestoreOnStartup
, out
).get());
602 // An incoming sync transaction should change the user value, not the managed
604 base::ListValue sync_value
;
605 sync_value
.Append(new base::StringValue("http://crbug.com"));
606 syncer::SyncChangeList list
;
607 list
.push_back(MakeRemoteChange(
608 1, prefs::kURLsToRestoreOnStartup
, sync_value
,
609 SyncChange::ACTION_UPDATE
));
610 pref_sync_service_
->ProcessSyncChanges(FROM_HERE
, list
);
612 EXPECT_TRUE(managed_value
.Equals(
613 prefs_
.GetManagedPref(prefs::kURLsToRestoreOnStartup
)));
614 EXPECT_TRUE(sync_value
.Equals(
615 prefs_
.GetUserPref(prefs::kURLsToRestoreOnStartup
)));
618 TEST_F(PrefServiceSyncableTest
, DynamicManagedPreferences
) {
619 syncer::SyncChangeList out
;
620 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out
);
622 base::StringValue
initial_value("http://example.com/initial");
623 GetPrefs()->Set(prefs::kHomePage
, initial_value
);
624 scoped_ptr
<base::Value
> actual(FindValue(prefs::kHomePage
, out
));
625 ASSERT_TRUE(actual
.get());
626 EXPECT_TRUE(initial_value
.Equals(actual
.get()));
628 // Switch kHomePage to managed and set a different value.
629 base::StringValue
managed_value("http://example.com/managed");
630 GetTestingPrefService()->SetManagedPref(prefs::kHomePage
,
631 managed_value
.DeepCopy());
633 // The pref value should be the one dictated by policy.
634 EXPECT_TRUE(managed_value
.Equals(&GetPreferenceValue(prefs::kHomePage
)));
636 // Switch kHomePage back to unmanaged.
637 GetTestingPrefService()->RemoveManagedPref(prefs::kHomePage
);
639 // The original value should be picked up.
640 EXPECT_TRUE(initial_value
.Equals(&GetPreferenceValue(prefs::kHomePage
)));
643 TEST_F(PrefServiceSyncableTest
, DynamicManagedPreferencesWithSyncChange
) {
644 syncer::SyncChangeList out
;
645 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out
);
648 base::StringValue
initial_value("http://example.com/initial");
649 GetPrefs()->Set(prefs::kHomePage
, initial_value
);
650 scoped_ptr
<base::Value
> actual(FindValue(prefs::kHomePage
, out
));
651 EXPECT_TRUE(initial_value
.Equals(actual
.get()));
653 // Switch kHomePage to managed and set a different value.
654 base::StringValue
managed_value("http://example.com/managed");
655 GetTestingPrefService()->SetManagedPref(prefs::kHomePage
,
656 managed_value
.DeepCopy());
658 // Change the sync value.
659 base::StringValue
sync_value("http://example.com/sync");
660 syncer::SyncChangeList list
;
661 list
.push_back(MakeRemoteChange(
662 1, prefs::kHomePage
, sync_value
, SyncChange::ACTION_UPDATE
));
663 pref_sync_service_
->ProcessSyncChanges(FROM_HERE
, list
);
665 // The pref value should still be the one dictated by policy.
666 EXPECT_TRUE(managed_value
.Equals(&GetPreferenceValue(prefs::kHomePage
)));
668 // Switch kHomePage back to unmanaged.
669 GetTestingPrefService()->RemoveManagedPref(prefs::kHomePage
);
671 // Sync value should be picked up.
672 EXPECT_TRUE(sync_value
.Equals(&GetPreferenceValue(prefs::kHomePage
)));
675 TEST_F(PrefServiceSyncableTest
, DynamicManagedDefaultPreferences
) {
676 const PrefService::Preference
* pref
=
677 prefs_
.FindPreference(prefs::kHomePage
);
678 EXPECT_TRUE(pref
->IsDefaultValue());
679 syncer::SyncChangeList out
;
680 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out
);
682 EXPECT_TRUE(IsSynced(prefs::kHomePage
));
683 EXPECT_TRUE(pref
->IsDefaultValue());
684 EXPECT_FALSE(FindValue(prefs::kHomePage
, out
).get());
687 // Switch kHomePage to managed and set a different value.
688 base::StringValue
managed_value("http://example.com/managed");
689 GetTestingPrefService()->SetManagedPref(prefs::kHomePage
,
690 managed_value
.DeepCopy());
691 // The pref value should be the one dictated by policy.
692 EXPECT_TRUE(managed_value
.Equals(&GetPreferenceValue(prefs::kHomePage
)));
693 EXPECT_FALSE(pref
->IsDefaultValue());
694 // There should be no synced value.
695 EXPECT_FALSE(FindValue(prefs::kHomePage
, out
).get());
696 // Switch kHomePage back to unmanaged.
697 GetTestingPrefService()->RemoveManagedPref(prefs::kHomePage
);
698 // The original value should be picked up.
699 EXPECT_TRUE(pref
->IsDefaultValue());
700 // There should still be no synced value.
701 EXPECT_FALSE(FindValue(prefs::kHomePage
, out
).get());
704 TEST_F(PrefServiceSyncableTest
, DeletePreference
) {
705 prefs_
.SetString(prefs::kHomePage
, kExampleUrl0
);
706 const PrefService::Preference
* pref
=
707 prefs_
.FindPreference(prefs::kHomePage
);
708 EXPECT_FALSE(pref
->IsDefaultValue());
710 InitWithNoSyncData();
712 scoped_ptr
<base::Value
> null_value
= base::Value::CreateNullValue();
713 syncer::SyncChangeList list
;
714 list
.push_back(MakeRemoteChange(
715 1, prefs::kHomePage
, *null_value
, SyncChange::ACTION_DELETE
));
716 pref_sync_service_
->ProcessSyncChanges(FROM_HERE
, list
);
717 EXPECT_TRUE(pref
->IsDefaultValue());