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 "components/syncable_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 "components/pref_registry/pref_registry_syncable.h"
14 #include "components/syncable_prefs/pref_model_associator.h"
15 #include "components/syncable_prefs/pref_model_associator_client.h"
16 #include "components/syncable_prefs/testing_pref_service_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"
27 using syncer::SyncChange
;
28 using syncer::SyncData
;
30 namespace syncable_prefs
{
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 kStringPrefName
[] = "string_pref_name";
38 const char kListPrefName
[] = "new_list_pref_name";
39 const char kListOldPrefName
[] = "list_pref_name";
40 const char kUnsyncedPreferenceName
[] = "nonsense_pref_name";
41 const char kUnsyncedPreferenceDefaultValue
[] = "default";
42 const char kDefaultCharsetPrefName
[] = "default_charset";
43 const char kNonDefaultCharsetValue
[] = "foo";
44 const char kDefaultCharsetValue
[] = "utf-8";
46 class TestPrefModelAssociatorClient
: public PrefModelAssociatorClient
{
48 TestPrefModelAssociatorClient() {}
49 ~TestPrefModelAssociatorClient() override
{}
51 // PrefModelAssociatorClient implementation.
52 bool IsMergeableListPreference(const std::string
& pref_name
) const override
{
53 return pref_name
== kListPrefName
;
56 bool IsMergeableDictionaryPreference(
57 const std::string
& pref_name
) const override
{
61 bool IsMigratedPreference(const std::string
& new_pref_name
,
62 std::string
* old_pref_name
) const override
{
63 if (new_pref_name
!= kListPrefName
)
65 old_pref_name
->assign(kListOldPrefName
);
69 bool IsOldMigratedPreference(const std::string
& old_pref_name
,
70 std::string
* new_pref_name
) const override
{
71 if (old_pref_name
!= kListOldPrefName
)
73 new_pref_name
->assign(kListPrefName
);
78 DISALLOW_COPY_AND_ASSIGN(TestPrefModelAssociatorClient
);
81 class TestSyncProcessorStub
: public syncer::SyncChangeProcessor
{
83 explicit TestSyncProcessorStub(syncer::SyncChangeList
* output
)
84 : output_(output
), fail_next_(false) {}
85 syncer::SyncError
ProcessSyncChanges(
86 const tracked_objects::Location
& from_here
,
87 const syncer::SyncChangeList
& change_list
) override
{
89 output_
->insert(output_
->end(), change_list
.begin(), change_list
.end());
92 return syncer::SyncError(
93 FROM_HERE
, syncer::SyncError::DATATYPE_ERROR
, "Error",
96 return syncer::SyncError();
99 void FailNextProcessSyncChanges() {
103 syncer::SyncDataList
GetAllSyncData(syncer::ModelType type
) const override
{
104 return syncer::SyncDataList();
107 syncer::SyncChangeList
* output_
;
111 class PrefServiceSyncableTest
: public testing::Test
{
113 PrefServiceSyncableTest()
114 : pref_sync_service_(NULL
),
115 test_processor_(NULL
),
116 next_pref_remote_sync_node_id_(0) {}
118 void SetUp() override
{
119 prefs_
.SetPrefModelAssociatorClientForTesting(&client_
);
120 prefs_
.registry()->RegisterStringPref(kUnsyncedPreferenceName
,
121 kUnsyncedPreferenceDefaultValue
);
122 prefs_
.registry()->RegisterStringPref(
125 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
126 prefs_
.registry()->RegisterListPref(
128 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
129 prefs_
.registry()->RegisterListPref(kListOldPrefName
);
130 prefs_
.registry()->RegisterStringPref(
131 kDefaultCharsetPrefName
,
132 kDefaultCharsetValue
,
133 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
135 pref_sync_service_
= reinterpret_cast<PrefModelAssociator
*>(
136 prefs_
.GetSyncableService(syncer::PREFERENCES
));
137 ASSERT_TRUE(pref_sync_service_
);
138 next_pref_remote_sync_node_id_
= 0;
141 syncer::SyncChange
MakeRemoteChange(
143 const std::string
& name
,
144 const base::Value
& value
,
145 SyncChange::SyncChangeType type
) {
146 std::string serialized
;
147 JSONStringValueSerializer
json(&serialized
);
148 if (!json
.Serialize(value
))
149 return syncer::SyncChange();
150 sync_pb::EntitySpecifics entity
;
151 sync_pb::PreferenceSpecifics
* pref_one
= entity
.mutable_preference();
152 pref_one
->set_name(name
);
153 pref_one
->set_value(serialized
);
154 return syncer::SyncChange(
157 syncer::SyncData::CreateRemoteData(
161 syncer::AttachmentIdList(),
162 syncer::AttachmentServiceProxyForTest::Create()));
165 void AddToRemoteDataList(const std::string
& name
,
166 const base::Value
& value
,
167 syncer::SyncDataList
* out
) {
168 std::string serialized
;
169 JSONStringValueSerializer
json(&serialized
);
170 ASSERT_TRUE(json
.Serialize(value
));
171 sync_pb::EntitySpecifics one
;
172 sync_pb::PreferenceSpecifics
* pref_one
= one
.mutable_preference();
173 pref_one
->set_name(name
);
174 pref_one
->set_value(serialized
);
175 out
->push_back(SyncData::CreateRemoteData(
176 ++next_pref_remote_sync_node_id_
,
179 syncer::AttachmentIdList(),
180 syncer::AttachmentServiceProxyForTest::Create()));
183 void InitWithSyncDataTakeOutput(const syncer::SyncDataList
& initial_data
,
184 syncer::SyncChangeList
* output
) {
185 test_processor_
= new TestSyncProcessorStub(output
);
186 syncer::SyncMergeResult r
= pref_sync_service_
->MergeDataAndStartSyncing(
187 syncer::PREFERENCES
, initial_data
,
188 scoped_ptr
<syncer::SyncChangeProcessor
>(test_processor_
),
189 scoped_ptr
<syncer::SyncErrorFactory
>(
190 new syncer::SyncErrorFactoryMock()));
191 EXPECT_FALSE(r
.error().IsSet());
194 void InitWithNoSyncData() {
195 InitWithSyncDataTakeOutput(syncer::SyncDataList(), NULL
);
198 const base::Value
& GetPreferenceValue(const std::string
& name
) {
199 const PrefService::Preference
* preference
=
200 prefs_
.FindPreference(name
.c_str());
201 return *preference
->GetValue();
204 scoped_ptr
<base::Value
> FindValue(const std::string
& name
,
205 const syncer::SyncChangeList
& list
) {
206 syncer::SyncChangeList::const_iterator it
= list
.begin();
207 for (; it
!= list
.end(); ++it
) {
208 if (syncer::SyncDataLocal(it
->sync_data()).GetTag() == name
) {
209 return base::JSONReader::Read(
210 it
->sync_data().GetSpecifics().preference().value());
213 return scoped_ptr
<base::Value
>();
216 bool IsSynced(const std::string
& pref_name
) {
217 return pref_sync_service_
->registered_preferences().count(pref_name
) > 0;
220 bool HasSyncData(const std::string
& pref_name
) {
221 return pref_sync_service_
->IsPrefSynced(pref_name
);
224 // Returns whether a given preference name is a new name of a migrated
225 // preference. Exposed here for testing.
226 bool IsMigratedPreference(const char* preference_name
) {
227 std::string old_pref_name
;
228 return client_
.IsMigratedPreference(preference_name
, &old_pref_name
);
231 bool IsOldMigratedPreference(const char* old_preference_name
) {
232 std::string new_pref_name
;
233 return client_
.IsOldMigratedPreference(old_preference_name
, &new_pref_name
);
236 PrefService
* GetPrefs() { return &prefs_
; }
237 TestingPrefServiceSyncable
* GetTestingPrefService() { return &prefs_
; }
240 TestPrefModelAssociatorClient client_
;
241 TestingPrefServiceSyncable prefs_
;
243 PrefModelAssociator
* pref_sync_service_
;
244 TestSyncProcessorStub
* test_processor_
;
246 // TODO(tim): Remove this by fixing AttachmentServiceProxyForTest.
247 base::MessageLoop loop_
;
249 int next_pref_remote_sync_node_id_
;
252 TEST_F(PrefServiceSyncableTest
, CreatePrefSyncData
) {
253 prefs_
.SetString(kStringPrefName
, kExampleUrl0
);
255 const PrefService::Preference
* pref
= prefs_
.FindPreference(kStringPrefName
);
256 syncer::SyncData sync_data
;
257 EXPECT_TRUE(pref_sync_service_
->CreatePrefSyncData(pref
->name(),
258 *pref
->GetValue(), &sync_data
));
259 EXPECT_EQ(std::string(kStringPrefName
),
260 syncer::SyncDataLocal(sync_data
).GetTag());
261 const sync_pb::PreferenceSpecifics
& specifics(sync_data
.GetSpecifics().
263 EXPECT_EQ(std::string(kStringPrefName
), specifics
.name());
265 scoped_ptr
<base::Value
> value
= base::JSONReader::Read(specifics
.value());
266 EXPECT_TRUE(pref
->GetValue()->Equals(value
.get()));
269 TEST_F(PrefServiceSyncableTest
, ModelAssociationDoNotSyncDefaults
) {
270 const PrefService::Preference
* pref
= prefs_
.FindPreference(kStringPrefName
);
271 EXPECT_TRUE(pref
->IsDefaultValue());
272 syncer::SyncChangeList out
;
273 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out
);
275 EXPECT_TRUE(IsSynced(kStringPrefName
));
276 EXPECT_TRUE(pref
->IsDefaultValue());
277 EXPECT_FALSE(FindValue(kStringPrefName
, out
).get());
280 TEST_F(PrefServiceSyncableTest
, ModelAssociationEmptyCloud
) {
281 prefs_
.SetString(kStringPrefName
, kExampleUrl0
);
283 ListPrefUpdate
update(GetPrefs(), kListPrefName
);
284 base::ListValue
* url_list
= update
.Get();
285 url_list
->Append(new base::StringValue(kExampleUrl0
));
286 url_list
->Append(new base::StringValue(kExampleUrl1
));
288 syncer::SyncChangeList out
;
289 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out
);
291 scoped_ptr
<base::Value
> value(FindValue(kStringPrefName
, out
));
292 ASSERT_TRUE(value
.get());
293 EXPECT_TRUE(GetPreferenceValue(kStringPrefName
).Equals(value
.get()));
294 value
= FindValue(kListPrefName
, out
).Pass();
295 ASSERT_TRUE(value
.get());
296 EXPECT_TRUE(GetPreferenceValue(kListPrefName
).Equals(value
.get()));
299 TEST_F(PrefServiceSyncableTest
, ModelAssociationCloudHasData
) {
300 prefs_
.SetString(kStringPrefName
, kExampleUrl0
);
302 ListPrefUpdate
update(GetPrefs(), kListPrefName
);
303 base::ListValue
* url_list
= update
.Get();
304 url_list
->Append(new base::StringValue(kExampleUrl0
));
305 url_list
->Append(new base::StringValue(kExampleUrl1
));
308 syncer::SyncDataList in
;
309 syncer::SyncChangeList out
;
310 AddToRemoteDataList(kStringPrefName
, base::StringValue(kExampleUrl1
), &in
);
311 base::ListValue urls_to_restore
;
312 urls_to_restore
.Append(new base::StringValue(kExampleUrl1
));
313 urls_to_restore
.Append(new base::StringValue(kExampleUrl2
));
314 AddToRemoteDataList(kListPrefName
, urls_to_restore
, &in
);
315 AddToRemoteDataList(kDefaultCharsetPrefName
,
316 base::StringValue(kNonDefaultCharsetValue
),
318 InitWithSyncDataTakeOutput(in
, &out
);
320 ASSERT_FALSE(FindValue(kStringPrefName
, out
).get());
321 ASSERT_FALSE(FindValue(kDefaultCharsetPrefName
, out
).get());
323 EXPECT_EQ(kExampleUrl1
, prefs_
.GetString(kStringPrefName
));
325 scoped_ptr
<base::ListValue
> expected_urls(new base::ListValue
);
326 expected_urls
->Append(new base::StringValue(kExampleUrl1
));
327 expected_urls
->Append(new base::StringValue(kExampleUrl2
));
328 expected_urls
->Append(new base::StringValue(kExampleUrl0
));
329 scoped_ptr
<base::Value
> value(FindValue(kListPrefName
, out
));
330 ASSERT_TRUE(value
.get());
331 EXPECT_TRUE(value
->Equals(expected_urls
.get()));
332 EXPECT_TRUE(GetPreferenceValue(kListPrefName
).Equals(expected_urls
.get()));
333 EXPECT_EQ(kNonDefaultCharsetValue
, prefs_
.GetString(kDefaultCharsetPrefName
));
336 TEST_F(PrefServiceSyncableTest
, ModelAssociationMigrateOldData
) {
337 ASSERT_TRUE(IsMigratedPreference(kListPrefName
));
338 ASSERT_TRUE(IsOldMigratedPreference(kListOldPrefName
));
340 syncer::SyncDataList in
;
341 syncer::SyncChangeList out
;
342 base::ListValue urls_to_restore
;
343 urls_to_restore
.Append(new base::StringValue(kExampleUrl1
));
344 urls_to_restore
.Append(new base::StringValue(kExampleUrl2
));
345 AddToRemoteDataList(kListOldPrefName
, urls_to_restore
, &in
);
346 InitWithSyncDataTakeOutput(in
, &out
);
348 // Expect that the new preference data contains the old pref's values.
349 scoped_ptr
<base::ListValue
> expected_urls(new base::ListValue
);
350 expected_urls
->Append(new base::StringValue(kExampleUrl1
));
351 expected_urls
->Append(new base::StringValue(kExampleUrl2
));
353 ASSERT_TRUE(HasSyncData(kListPrefName
));
354 scoped_ptr
<base::Value
> value(FindValue(kListPrefName
, out
));
355 ASSERT_TRUE(value
.get());
356 EXPECT_TRUE(value
->Equals(expected_urls
.get()));
357 EXPECT_TRUE(GetPreferenceValue(kListPrefName
).Equals(expected_urls
.get()));
359 // The old preference value should be the same.
360 expected_urls
.reset(new base::ListValue
);
361 ASSERT_FALSE(FindValue(kListOldPrefName
, out
).get());
362 EXPECT_TRUE(GetPreferenceValue(kListOldPrefName
).Equals(expected_urls
.get()));
365 TEST_F(PrefServiceSyncableTest
, ModelAssociationCloudHasOldMigratedData
) {
366 ASSERT_TRUE(IsMigratedPreference(kListPrefName
));
367 ASSERT_TRUE(IsOldMigratedPreference(kListOldPrefName
));
368 prefs_
.SetString(kStringPrefName
, kExampleUrl0
);
370 ListPrefUpdate
update(GetPrefs(), kListPrefName
);
371 base::ListValue
* url_list
= update
.Get();
372 url_list
->Append(new base::StringValue(kExampleUrl0
));
373 url_list
->Append(new base::StringValue(kExampleUrl1
));
376 syncer::SyncDataList in
;
377 syncer::SyncChangeList out
;
378 base::ListValue urls_to_restore
;
379 urls_to_restore
.Append(new base::StringValue(kExampleUrl1
));
380 urls_to_restore
.Append(new base::StringValue(kExampleUrl2
));
381 AddToRemoteDataList(kListOldPrefName
, urls_to_restore
, &in
);
382 AddToRemoteDataList(kStringPrefName
, base::StringValue(kExampleUrl1
), &in
);
383 InitWithSyncDataTakeOutput(in
, &out
);
385 ASSERT_FALSE(FindValue(kStringPrefName
, out
).get());
387 // Expect that the new preference data contains the merged old prefs values.
388 scoped_ptr
<base::ListValue
> expected_urls(new base::ListValue
);
389 expected_urls
->Append(new base::StringValue(kExampleUrl1
));
390 expected_urls
->Append(new base::StringValue(kExampleUrl2
));
391 expected_urls
->Append(new base::StringValue(kExampleUrl0
));
393 ASSERT_TRUE(HasSyncData(kListPrefName
));
394 scoped_ptr
<base::Value
> value(FindValue(kListPrefName
, out
));
395 ASSERT_TRUE(value
.get());
396 EXPECT_TRUE(value
->Equals(expected_urls
.get()));
397 EXPECT_TRUE(GetPreferenceValue(kListPrefName
).Equals(expected_urls
.get()));
399 expected_urls
.reset(new base::ListValue
);
400 value
= FindValue(kListOldPrefName
, out
).Pass();
401 ASSERT_TRUE(value
.get());
402 EXPECT_TRUE(GetPreferenceValue(kListOldPrefName
).Equals(expected_urls
.get()));
405 TEST_F(PrefServiceSyncableTest
, ModelAssociationCloudHasNewMigratedData
) {
406 ASSERT_TRUE(IsMigratedPreference(kListPrefName
));
407 ASSERT_TRUE(IsOldMigratedPreference(kListOldPrefName
));
408 prefs_
.SetString(kStringPrefName
, kExampleUrl0
);
410 ListPrefUpdate
update(GetPrefs(), kListOldPrefName
);
411 base::ListValue
* url_list
= update
.Get();
412 url_list
->Append(new base::StringValue(kExampleUrl0
));
413 url_list
->Append(new base::StringValue(kExampleUrl1
));
416 syncer::SyncDataList in
;
417 syncer::SyncChangeList out
;
418 base::ListValue urls_to_restore
;
419 urls_to_restore
.Append(new base::StringValue(kExampleUrl1
));
420 urls_to_restore
.Append(new base::StringValue(kExampleUrl2
));
421 AddToRemoteDataList(kListOldPrefName
, urls_to_restore
, &in
);
422 AddToRemoteDataList(kStringPrefName
, base::StringValue(kExampleUrl1
), &in
);
423 InitWithSyncDataTakeOutput(in
, &out
);
425 scoped_ptr
<base::Value
> value(FindValue(kStringPrefName
, out
));
426 ASSERT_FALSE(value
.get());
428 // Expect that the cloud data under the new migrated preference name sticks.
429 scoped_ptr
<base::ListValue
> expected_urls(new base::ListValue
);
430 expected_urls
->Append(new base::StringValue(kExampleUrl1
));
431 expected_urls
->Append(new base::StringValue(kExampleUrl2
));
433 ASSERT_TRUE(HasSyncData(kListPrefName
));
434 value
= FindValue(kListPrefName
, out
).Pass();
435 ASSERT_TRUE(value
.get());
436 EXPECT_TRUE(value
->Equals(expected_urls
.get()));
437 EXPECT_TRUE(GetPreferenceValue(kListPrefName
).Equals(expected_urls
.get()));
439 // The old preference data should still be here, though not synced.
440 expected_urls
.reset(new base::ListValue
);
441 expected_urls
->Append(new base::StringValue(kExampleUrl0
));
442 expected_urls
->Append(new base::StringValue(kExampleUrl1
));
444 value
= FindValue(kListOldPrefName
, out
).Pass();
445 ASSERT_FALSE(value
.get());
446 EXPECT_TRUE(GetPreferenceValue(kListOldPrefName
).Equals(expected_urls
.get()));
449 TEST_F(PrefServiceSyncableTest
,
450 ModelAssociationCloudAddsOldAndNewMigratedData
) {
451 ASSERT_TRUE(IsMigratedPreference(kListPrefName
));
452 ASSERT_TRUE(IsOldMigratedPreference(kListOldPrefName
));
453 prefs_
.SetString(kStringPrefName
, kExampleUrl0
);
455 ListPrefUpdate
update_old(GetPrefs(), kListOldPrefName
);
456 base::ListValue
* url_list_old
= update_old
.Get();
457 url_list_old
->Append(new base::StringValue(kExampleUrl0
));
458 url_list_old
->Append(new base::StringValue(kExampleUrl1
));
459 ListPrefUpdate
update(GetPrefs(), kListPrefName
);
460 base::ListValue
* url_list
= update
.Get();
461 url_list
->Append(new base::StringValue(kExampleUrl1
));
462 url_list
->Append(new base::StringValue(kExampleUrl2
));
465 syncer::SyncDataList in
;
466 syncer::SyncChangeList out
;
467 AddToRemoteDataList(kStringPrefName
, base::StringValue(kExampleUrl1
), &in
);
468 InitWithSyncDataTakeOutput(in
, &out
);
470 scoped_ptr
<base::Value
> value(FindValue(kStringPrefName
, out
));
471 ASSERT_FALSE(value
.get());
473 // Expect that the cloud data under the new migrated preference name sticks.
474 scoped_ptr
<base::ListValue
> expected_urls(new base::ListValue
);
475 expected_urls
->Append(new base::StringValue(kExampleUrl1
));
476 expected_urls
->Append(new base::StringValue(kExampleUrl2
));
478 ASSERT_TRUE(HasSyncData(kListPrefName
));
479 value
= FindValue(kListPrefName
, out
).Pass();
480 ASSERT_TRUE(value
.get());
481 EXPECT_TRUE(value
->Equals(expected_urls
.get()));
482 EXPECT_TRUE(GetPreferenceValue(kListPrefName
).Equals(expected_urls
.get()));
484 // Should not have synced in the old startup url values.
485 value
= FindValue(kListOldPrefName
, out
).Pass();
486 ASSERT_FALSE(value
.get());
488 GetPreferenceValue(kListOldPrefName
).Equals(expected_urls
.get()));
491 TEST_F(PrefServiceSyncableTest
, FailModelAssociation
) {
492 syncer::SyncChangeList output
;
493 TestSyncProcessorStub
* stub
= new TestSyncProcessorStub(&output
);
494 stub
->FailNextProcessSyncChanges();
495 syncer::SyncMergeResult r
= pref_sync_service_
->MergeDataAndStartSyncing(
496 syncer::PREFERENCES
, syncer::SyncDataList(),
497 scoped_ptr
<syncer::SyncChangeProcessor
>(stub
),
498 scoped_ptr
<syncer::SyncErrorFactory
>(
499 new syncer::SyncErrorFactoryMock()));
500 EXPECT_TRUE(r
.error().IsSet());
503 TEST_F(PrefServiceSyncableTest
, UpdatedPreferenceWithDefaultValue
) {
504 const PrefService::Preference
* pref
= prefs_
.FindPreference(kStringPrefName
);
505 EXPECT_TRUE(pref
->IsDefaultValue());
507 syncer::SyncChangeList out
;
508 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out
);
511 base::StringValue
expected(kExampleUrl0
);
512 GetPrefs()->Set(kStringPrefName
, expected
);
514 scoped_ptr
<base::Value
> actual(FindValue(kStringPrefName
, out
));
515 ASSERT_TRUE(actual
.get());
516 EXPECT_TRUE(expected
.Equals(actual
.get()));
519 TEST_F(PrefServiceSyncableTest
, UpdatedPreferenceWithValue
) {
520 GetPrefs()->SetString(kStringPrefName
, kExampleUrl0
);
521 syncer::SyncChangeList out
;
522 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out
);
525 base::StringValue
expected(kExampleUrl1
);
526 GetPrefs()->Set(kStringPrefName
, expected
);
528 scoped_ptr
<base::Value
> actual(FindValue(kStringPrefName
, out
));
529 ASSERT_TRUE(actual
.get());
530 EXPECT_TRUE(expected
.Equals(actual
.get()));
533 TEST_F(PrefServiceSyncableTest
, UpdatedSyncNodeActionUpdate
) {
534 GetPrefs()->SetString(kStringPrefName
, kExampleUrl0
);
535 InitWithNoSyncData();
537 base::StringValue
expected(kExampleUrl1
);
538 syncer::SyncChangeList list
;
539 list
.push_back(MakeRemoteChange(
540 1, kStringPrefName
, expected
, SyncChange::ACTION_UPDATE
));
541 pref_sync_service_
->ProcessSyncChanges(FROM_HERE
, list
);
543 const base::Value
& actual
= GetPreferenceValue(kStringPrefName
);
544 EXPECT_TRUE(expected
.Equals(&actual
));
547 TEST_F(PrefServiceSyncableTest
, UpdatedSyncNodeActionAdd
) {
548 InitWithNoSyncData();
550 base::StringValue
expected(kExampleUrl0
);
551 syncer::SyncChangeList list
;
552 list
.push_back(MakeRemoteChange(
553 1, kStringPrefName
, expected
, SyncChange::ACTION_ADD
));
554 pref_sync_service_
->ProcessSyncChanges(FROM_HERE
, list
);
556 const base::Value
& actual
= GetPreferenceValue(kStringPrefName
);
557 EXPECT_TRUE(expected
.Equals(&actual
));
559 pref_sync_service_
->registered_preferences().count(kStringPrefName
));
562 TEST_F(PrefServiceSyncableTest
, UpdatedSyncNodeUnknownPreference
) {
563 InitWithNoSyncData();
564 syncer::SyncChangeList list
;
565 base::StringValue
expected(kExampleUrl0
);
566 list
.push_back(MakeRemoteChange(
567 1, "unknown preference", expected
, SyncChange::ACTION_UPDATE
));
568 pref_sync_service_
->ProcessSyncChanges(FROM_HERE
, list
);
569 // Nothing interesting happens on the client when it gets an update
570 // of an unknown preference. We just should not crash.
573 TEST_F(PrefServiceSyncableTest
, ManagedPreferences
) {
574 // Make the homepage preference managed.
575 base::StringValue
managed_value("http://example.com");
576 prefs_
.SetManagedPref(kStringPrefName
, managed_value
.DeepCopy());
578 syncer::SyncChangeList out
;
579 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out
);
582 // Changing the homepage preference should not sync anything.
583 base::StringValue
user_value("http://chromium..com");
584 prefs_
.SetUserPref(kStringPrefName
, user_value
.DeepCopy());
585 EXPECT_TRUE(out
.empty());
587 // An incoming sync transaction should change the user value, not the managed
589 base::StringValue
sync_value("http://crbug.com");
590 syncer::SyncChangeList list
;
591 list
.push_back(MakeRemoteChange(
592 1, kStringPrefName
, sync_value
, SyncChange::ACTION_UPDATE
));
593 pref_sync_service_
->ProcessSyncChanges(FROM_HERE
, list
);
595 EXPECT_TRUE(managed_value
.Equals(prefs_
.GetManagedPref(kStringPrefName
)));
596 EXPECT_TRUE(sync_value
.Equals(prefs_
.GetUserPref(kStringPrefName
)));
599 // List preferences have special handling at association time due to our ability
600 // to merge the local and sync value. Make sure the merge logic doesn't merge
601 // managed preferences.
602 TEST_F(PrefServiceSyncableTest
, ManagedListPreferences
) {
603 // Make the list of urls to restore on startup managed.
604 base::ListValue managed_value
;
605 managed_value
.Append(new base::StringValue(kExampleUrl0
));
606 managed_value
.Append(new base::StringValue(kExampleUrl1
));
607 prefs_
.SetManagedPref(kListPrefName
, managed_value
.DeepCopy());
609 // Set a cloud version.
610 syncer::SyncDataList in
;
611 syncer::SyncChangeList out
;
612 base::ListValue urls_to_restore
;
613 urls_to_restore
.Append(new base::StringValue(kExampleUrl1
));
614 urls_to_restore
.Append(new base::StringValue(kExampleUrl2
));
615 AddToRemoteDataList(kListPrefName
, urls_to_restore
, &in
);
617 // Start sync and verify the synced value didn't get merged.
618 InitWithSyncDataTakeOutput(in
, &out
);
619 EXPECT_FALSE(FindValue(kListPrefName
, out
).get());
622 // Changing the user's urls to restore on startup pref should not sync
624 base::ListValue user_value
;
625 user_value
.Append(new base::StringValue("http://chromium.org"));
626 prefs_
.SetUserPref(kListPrefName
, user_value
.DeepCopy());
627 EXPECT_FALSE(FindValue(kListPrefName
, out
).get());
629 // An incoming sync transaction should change the user value, not the managed
631 base::ListValue sync_value
;
632 sync_value
.Append(new base::StringValue("http://crbug.com"));
633 syncer::SyncChangeList list
;
634 list
.push_back(MakeRemoteChange(
635 1, kListPrefName
, sync_value
,
636 SyncChange::ACTION_UPDATE
));
637 pref_sync_service_
->ProcessSyncChanges(FROM_HERE
, list
);
639 EXPECT_TRUE(managed_value
.Equals(prefs_
.GetManagedPref(kListPrefName
)));
640 EXPECT_TRUE(sync_value
.Equals(prefs_
.GetUserPref(kListPrefName
)));
643 TEST_F(PrefServiceSyncableTest
, DynamicManagedPreferences
) {
644 syncer::SyncChangeList out
;
645 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out
);
647 base::StringValue
initial_value("http://example.com/initial");
648 GetPrefs()->Set(kStringPrefName
, initial_value
);
649 scoped_ptr
<base::Value
> actual(FindValue(kStringPrefName
, out
));
650 ASSERT_TRUE(actual
.get());
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(kStringPrefName
,
656 managed_value
.DeepCopy());
658 // The pref value should be the one dictated by policy.
659 EXPECT_TRUE(managed_value
.Equals(&GetPreferenceValue(kStringPrefName
)));
661 // Switch kHomePage back to unmanaged.
662 GetTestingPrefService()->RemoveManagedPref(kStringPrefName
);
664 // The original value should be picked up.
665 EXPECT_TRUE(initial_value
.Equals(&GetPreferenceValue(kStringPrefName
)));
668 TEST_F(PrefServiceSyncableTest
, DynamicManagedPreferencesWithSyncChange
) {
669 syncer::SyncChangeList out
;
670 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out
);
673 base::StringValue
initial_value("http://example.com/initial");
674 GetPrefs()->Set(kStringPrefName
, initial_value
);
675 scoped_ptr
<base::Value
> actual(FindValue(kStringPrefName
, out
));
676 EXPECT_TRUE(initial_value
.Equals(actual
.get()));
678 // Switch kHomePage to managed and set a different value.
679 base::StringValue
managed_value("http://example.com/managed");
680 GetTestingPrefService()->SetManagedPref(kStringPrefName
,
681 managed_value
.DeepCopy());
683 // Change the sync value.
684 base::StringValue
sync_value("http://example.com/sync");
685 syncer::SyncChangeList list
;
686 list
.push_back(MakeRemoteChange(
687 1, kStringPrefName
, sync_value
, SyncChange::ACTION_UPDATE
));
688 pref_sync_service_
->ProcessSyncChanges(FROM_HERE
, list
);
690 // The pref value should still be the one dictated by policy.
691 EXPECT_TRUE(managed_value
.Equals(&GetPreferenceValue(kStringPrefName
)));
693 // Switch kHomePage back to unmanaged.
694 GetTestingPrefService()->RemoveManagedPref(kStringPrefName
);
696 // Sync value should be picked up.
697 EXPECT_TRUE(sync_value
.Equals(&GetPreferenceValue(kStringPrefName
)));
700 TEST_F(PrefServiceSyncableTest
, DynamicManagedDefaultPreferences
) {
701 const PrefService::Preference
* pref
= prefs_
.FindPreference(kStringPrefName
);
702 EXPECT_TRUE(pref
->IsDefaultValue());
703 syncer::SyncChangeList out
;
704 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out
);
706 EXPECT_TRUE(IsSynced(kStringPrefName
));
707 EXPECT_TRUE(pref
->IsDefaultValue());
708 EXPECT_FALSE(FindValue(kStringPrefName
, out
).get());
711 // Switch kHomePage to managed and set a different value.
712 base::StringValue
managed_value("http://example.com/managed");
713 GetTestingPrefService()->SetManagedPref(kStringPrefName
,
714 managed_value
.DeepCopy());
715 // The pref value should be the one dictated by policy.
716 EXPECT_TRUE(managed_value
.Equals(&GetPreferenceValue(kStringPrefName
)));
717 EXPECT_FALSE(pref
->IsDefaultValue());
718 // There should be no synced value.
719 EXPECT_FALSE(FindValue(kStringPrefName
, out
).get());
720 // Switch kHomePage back to unmanaged.
721 GetTestingPrefService()->RemoveManagedPref(kStringPrefName
);
722 // The original value should be picked up.
723 EXPECT_TRUE(pref
->IsDefaultValue());
724 // There should still be no synced value.
725 EXPECT_FALSE(FindValue(kStringPrefName
, out
).get());
728 TEST_F(PrefServiceSyncableTest
, DeletePreference
) {
729 prefs_
.SetString(kStringPrefName
, kExampleUrl0
);
730 const PrefService::Preference
* pref
= prefs_
.FindPreference(kStringPrefName
);
731 EXPECT_FALSE(pref
->IsDefaultValue());
733 InitWithNoSyncData();
735 scoped_ptr
<base::Value
> null_value
= base::Value::CreateNullValue();
736 syncer::SyncChangeList list
;
737 list
.push_back(MakeRemoteChange(
738 1, kStringPrefName
, *null_value
, SyncChange::ACTION_DELETE
));
739 pref_sync_service_
->ProcessSyncChanges(FROM_HERE
, list
);
740 EXPECT_TRUE(pref
->IsDefaultValue());
745 } // namespace syncable_prefs