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