Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / sync / profile_sync_service_preference_unittest.cc
blobc13460fa94d53d68e1c4b5fdf24e63ddd6d40dc2
1 // Copyright (c) 2012 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 <map>
6 #include <string>
8 #include "base/bind.h"
9 #include "base/bind_helpers.h"
10 #include "base/callback.h"
11 #include "base/json/json_reader.h"
12 #include "base/json/json_string_value_serializer.h"
13 #include "base/json/json_writer.h"
14 #include "base/location.h"
15 #include "base/prefs/scoped_user_pref_update.h"
16 #include "base/stl_util.h"
17 #include "base/strings/string_piece.h"
18 #include "chrome/browser/invalidation/invalidation_service_factory.h"
19 #include "chrome/browser/prefs/pref_model_associator.h"
20 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
21 #include "chrome/browser/signin/signin_manager.h"
22 #include "chrome/browser/signin/signin_manager_factory.h"
23 #include "chrome/browser/sync/abstract_profile_sync_service_test.h"
24 #include "chrome/browser/sync/fake_oauth2_token_service_for_sync.h"
25 #include "chrome/browser/sync/glue/generic_change_processor.h"
26 #include "chrome/browser/sync/glue/sync_backend_host.h"
27 #include "chrome/browser/sync/glue/ui_data_type_controller.h"
28 #include "chrome/browser/sync/profile_sync_service_factory.h"
29 #include "chrome/browser/sync/profile_sync_test_util.h"
30 #include "chrome/browser/sync/test_profile_sync_service.h"
31 #include "chrome/common/pref_names.h"
32 #include "chrome/test/base/testing_pref_service_syncable.h"
33 #include "chrome/test/base/testing_profile.h"
34 #include "components/user_prefs/pref_registry_syncable.h"
35 #include "google_apis/gaia/gaia_constants.h"
36 #include "sync/api/sync_data.h"
37 #include "sync/internal_api/public/base/model_type.h"
38 #include "sync/internal_api/public/change_record.h"
39 #include "sync/internal_api/public/data_type_debug_info_listener.h"
40 #include "sync/internal_api/public/read_node.h"
41 #include "sync/internal_api/public/read_transaction.h"
42 #include "sync/internal_api/public/write_node.h"
43 #include "sync/internal_api/public/write_transaction.h"
44 #include "sync/protocol/preference_specifics.pb.h"
45 #include "testing/gmock/include/gmock/gmock.h"
46 #include "testing/gtest/include/gtest/gtest.h"
48 using base::JSONReader;
49 using browser_sync::GenericChangeProcessor;
50 using browser_sync::SharedChangeProcessor;
51 using browser_sync::UIDataTypeController;
52 using syncer::ChangeRecord;
53 using testing::_;
54 using testing::Invoke;
55 using testing::Return;
57 typedef std::map<const std::string, const base::Value*> PreferenceValues;
59 ACTION_P(CreateAndSaveChangeProcessor, change_processor) {
60 syncer::UserShare* user_share = arg0->GetUserShare();
61 *change_processor = new GenericChangeProcessor(arg1,
62 arg2,
63 arg3,
64 user_share);
65 return *change_processor;
68 ACTION_P(ReturnNewDataTypeManagerWithDebugListener, debug_listener) {
69 return new browser_sync::DataTypeManagerImpl(
70 debug_listener,
71 arg1,
72 arg2,
73 arg3,
74 arg4,
75 arg5);
78 // TODO(zea): Refactor to remove the ProfileSyncService usage.
79 class ProfileSyncServicePreferenceTest
80 : public AbstractProfileSyncServiceTest,
81 public syncer::DataTypeDebugInfoListener {
82 public:
83 int64 SetSyncedValue(const std::string& name, const base::Value& value) {
84 syncer::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare());
85 syncer::ReadNode root(&trans);
86 if (root.InitByTagLookup(syncer::ModelTypeToRootTag(
87 syncer::PREFERENCES)) != syncer::BaseNode::INIT_OK) {
88 return syncer::kInvalidId;
91 syncer::WriteNode tag_node(&trans);
92 syncer::WriteNode node(&trans);
94 if (tag_node.InitByClientTagLookup(syncer::PREFERENCES, name) ==
95 syncer::BaseNode::INIT_OK) {
96 return WriteSyncedValue(name, value, &tag_node);
99 syncer::WriteNode::InitUniqueByCreationResult result =
100 node.InitUniqueByCreation(syncer::PREFERENCES, root, name);
101 if (result == syncer::WriteNode::INIT_SUCCESS)
102 return WriteSyncedValue(name, value, &node);
104 return syncer::kInvalidId;
107 // DataTypeDebugInfoListener implementation.
108 virtual void OnDataTypeConfigureComplete(
109 const std::vector<syncer::DataTypeConfigurationStats>&
110 configuration_stats) OVERRIDE {
111 ASSERT_EQ(1u, configuration_stats.size());
112 association_stats_ = configuration_stats[0].association_stats;
115 protected:
116 ProfileSyncServicePreferenceTest()
117 : debug_ptr_factory_(this),
118 example_url0_("http://example.com/0"),
119 example_url1_("http://example.com/1"),
120 example_url2_("http://example.com/2"),
121 not_synced_preference_name_("nonsense_pref_name"),
122 not_synced_preference_default_value_("default"),
123 non_default_charset_value_("foo") {}
125 virtual void SetUp() {
126 AbstractProfileSyncServiceTest::SetUp();
127 TestingProfile::Builder builder;
128 builder.AddTestingFactory(ProfileOAuth2TokenServiceFactory::GetInstance(),
129 FakeOAuth2TokenServiceForSync::BuildTokenService);
130 profile_ = builder.Build().Pass();
131 invalidation::InvalidationServiceFactory::GetInstance()->
132 SetBuildOnlyFakeInvalidatorsForTest(true);
133 prefs_ = profile_->GetTestingPrefService();
135 prefs_->registry()->RegisterStringPref(
136 not_synced_preference_name_.c_str(),
137 not_synced_preference_default_value_,
138 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
141 virtual void TearDown() {
142 profile_.reset();
143 AbstractProfileSyncServiceTest::TearDown();
146 int GetSyncPreferenceCount() {
147 syncer::ReadTransaction trans(FROM_HERE, sync_service_->GetUserShare());
148 syncer::ReadNode node(&trans);
149 if (node.InitByTagLookup(syncer::ModelTypeToRootTag(syncer::PREFERENCES)) !=
150 syncer::BaseNode::INIT_OK)
151 return 0;
152 return node.GetTotalNodeCount() - 1;
155 bool StartSyncService(const base::Closure& callback,
156 bool will_fail_association) {
157 if (sync_service_)
158 return false;
160 SigninManagerBase* signin =
161 SigninManagerFactory::GetForProfile(profile_.get());
162 signin->SetAuthenticatedUsername("test");
163 sync_service_ = static_cast<TestProfileSyncService*>(
164 ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
165 profile_.get(), &TestProfileSyncService::BuildAutoStartAsyncInit));
166 sync_service_->set_backend_init_callback(callback);
167 pref_sync_service_ = reinterpret_cast<PrefModelAssociator*>(
168 prefs_->GetSyncableService(syncer::PREFERENCES));
169 if (!pref_sync_service_)
170 return false;
171 ProfileSyncComponentsFactoryMock* components =
172 sync_service_->components_factory_mock();
173 EXPECT_CALL(*components, GetSyncableServiceForType(syncer::PREFERENCES)).
174 WillOnce(Return(pref_sync_service_->AsWeakPtr()));
176 EXPECT_CALL(*components, CreateDataTypeManager(_, _, _, _, _, _)).
177 WillOnce(ReturnNewDataTypeManagerWithDebugListener(
178 syncer::MakeWeakHandle(debug_ptr_factory_.GetWeakPtr())));
179 dtc_ = new UIDataTypeController(syncer::PREFERENCES,
180 components,
181 profile_.get(),
182 sync_service_);
183 EXPECT_CALL(*components, CreateSharedChangeProcessor()).
184 WillOnce(Return(new SharedChangeProcessor()));
185 EXPECT_CALL(*components, CreateGenericChangeProcessor(_, _, _, _)).
186 WillOnce(CreateAndSaveChangeProcessor(
187 &change_processor_));
188 sync_service_->RegisterDataTypeController(dtc_);
189 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_.get())
190 ->UpdateCredentials("test", "oauth2_login_token");
192 sync_service_->Initialize();
193 base::MessageLoop::current()->Run();
195 // It's possible this test triggered an unrecoverable error, in which case
196 // we can't get the preference count.
197 if (sync_service_->ShouldPushChanges()) {
198 EXPECT_EQ(GetSyncPreferenceCount(),
199 association_stats_.num_sync_items_after_association);
201 EXPECT_EQ(association_stats_.num_sync_items_after_association,
202 association_stats_.num_sync_items_before_association +
203 association_stats_.num_sync_items_added -
204 association_stats_.num_sync_items_deleted);
206 return true;
209 const base::Value& GetPreferenceValue(const std::string& name) {
210 const PrefService::Preference* preference =
211 prefs_->FindPreference(name.c_str());
212 return *preference->GetValue();
215 // Caller gets ownership of the returned value.
216 const base::Value* GetSyncedValue(const std::string& name) {
217 syncer::ReadTransaction trans(FROM_HERE, sync_service_->GetUserShare());
218 syncer::ReadNode node(&trans);
220 if (node.InitByClientTagLookup(syncer::PREFERENCES, name) !=
221 syncer::BaseNode::INIT_OK) {
222 return NULL;
225 const sync_pb::PreferenceSpecifics& specifics(
226 node.GetEntitySpecifics().preference());
228 return base::JSONReader::Read(specifics.value());
231 int64 WriteSyncedValue(const std::string& name,
232 const base::Value& value,
233 syncer::WriteNode* node) {
234 syncer::SyncData sync_data;
235 if (!pref_sync_service_->CreatePrefSyncData(name,
236 value,
237 &sync_data)) {
238 return syncer::kInvalidId;
240 node->SetEntitySpecifics(sync_data.GetSpecifics());
241 return node->GetId();
244 bool IsSynced(const std::string& pref_name) {
245 return pref_sync_service_->registered_preferences().count(pref_name) > 0;
248 bool HasSyncData(const std::string& pref_name) {
249 return pref_sync_service_->IsPrefSynced(pref_name);
252 std::string ValueString(const base::Value& value) {
253 std::string serialized;
254 JSONStringValueSerializer json(&serialized);
255 json.Serialize(value);
256 return serialized;
259 // Returns whether a given preference name is a new name of a migrated
260 // preference. Exposed here for testing.
261 static bool IsMigratedPreference(const char* preference_name) {
262 return PrefModelAssociator::IsMigratedPreference(preference_name);
264 static bool IsOldMigratedPreference(const char* old_preference_name) {
265 return PrefModelAssociator::IsOldMigratedPreference(old_preference_name);
268 scoped_ptr<TestingProfile> profile_;
269 TestingPrefServiceSyncable* prefs_;
271 UIDataTypeController* dtc_;
272 PrefModelAssociator* pref_sync_service_;
273 GenericChangeProcessor* change_processor_;
274 syncer::DataTypeAssociationStats association_stats_;
275 base::WeakPtrFactory<DataTypeDebugInfoListener> debug_ptr_factory_;
277 std::string example_url0_;
278 std::string example_url1_;
279 std::string example_url2_;
280 std::string not_synced_preference_name_;
281 std::string not_synced_preference_default_value_;
282 std::string non_default_charset_value_;
285 class AddPreferenceEntriesHelper {
286 public:
287 AddPreferenceEntriesHelper(ProfileSyncServicePreferenceTest* test,
288 const PreferenceValues& entries)
289 : callback_(base::Bind(
290 &AddPreferenceEntriesHelper::AddPreferenceEntriesCallback,
291 base::Unretained(this), test, entries)),
292 success_(false) {
295 const base::Closure& callback() const { return callback_; }
296 bool success() { return success_; }
298 private:
299 void AddPreferenceEntriesCallback(ProfileSyncServicePreferenceTest* test,
300 const PreferenceValues& entries) {
301 if (!test->CreateRoot(syncer::PREFERENCES))
302 return;
304 for (PreferenceValues::const_iterator i = entries.begin();
305 i != entries.end(); ++i) {
306 if (test->SetSyncedValue(i->first, *i->second) == syncer::kInvalidId)
307 return;
309 success_ = true;
312 base::Closure callback_;
313 bool success_;
316 TEST_F(ProfileSyncServicePreferenceTest, CreatePrefSyncData) {
317 prefs_->SetString(prefs::kHomePage, example_url0_);
318 CreateRootHelper create_root(this, syncer::PREFERENCES);
319 ASSERT_TRUE(StartSyncService(create_root.callback(), false));
320 ASSERT_TRUE(create_root.success());
322 const PrefService::Preference* pref =
323 prefs_->FindPreference(prefs::kHomePage);
324 syncer::SyncData sync_data;
325 EXPECT_TRUE(pref_sync_service_->CreatePrefSyncData(pref->name(),
326 *pref->GetValue(), &sync_data));
327 EXPECT_EQ(std::string(prefs::kHomePage), sync_data.GetTag());
328 const sync_pb::PreferenceSpecifics& specifics(sync_data.GetSpecifics().
329 preference());
330 EXPECT_EQ(std::string(prefs::kHomePage), specifics.name());
332 scoped_ptr<base::Value> value(base::JSONReader::Read(specifics.value()));
333 EXPECT_TRUE(pref->GetValue()->Equals(value.get()));
336 TEST_F(ProfileSyncServicePreferenceTest, ModelAssociationDoNotSyncDefaults) {
337 const PrefService::Preference* pref =
338 prefs_->FindPreference(prefs::kHomePage);
339 EXPECT_TRUE(pref->IsDefaultValue());
340 CreateRootHelper create_root(this, syncer::PREFERENCES);
341 ASSERT_TRUE(StartSyncService(create_root.callback(), false));
342 ASSERT_TRUE(create_root.success());
343 EXPECT_TRUE(IsSynced(prefs::kHomePage));
344 EXPECT_TRUE(pref->IsDefaultValue());
345 EXPECT_TRUE(GetSyncedValue(prefs::kHomePage) == NULL);
346 EXPECT_TRUE(GetSyncedValue(not_synced_preference_name_) == NULL);
349 TEST_F(ProfileSyncServicePreferenceTest, ModelAssociationEmptyCloud) {
350 prefs_->SetString(prefs::kHomePage, example_url0_);
352 ListPrefUpdate update(prefs_, prefs::kURLsToRestoreOnStartup);
353 base::ListValue* url_list = update.Get();
354 url_list->Append(base::Value::CreateStringValue(example_url0_));
355 url_list->Append(base::Value::CreateStringValue(example_url1_));
357 CreateRootHelper create_root(this, syncer::PREFERENCES);
358 ASSERT_TRUE(StartSyncService(create_root.callback(), false));
359 ASSERT_TRUE(create_root.success());
361 scoped_ptr<const base::Value> value(GetSyncedValue(prefs::kHomePage));
362 ASSERT_TRUE(value.get());
363 EXPECT_TRUE(GetPreferenceValue(prefs::kHomePage).Equals(value.get()));
364 value.reset(GetSyncedValue(prefs::kURLsToRestoreOnStartup));
365 ASSERT_TRUE(value.get());
366 EXPECT_TRUE(
367 GetPreferenceValue(prefs::kURLsToRestoreOnStartup).Equals(value.get()));
370 TEST_F(ProfileSyncServicePreferenceTest, ModelAssociationCloudHasData) {
371 prefs_->SetString(prefs::kHomePage, example_url0_);
373 ListPrefUpdate update(prefs_, prefs::kURLsToRestoreOnStartup);
374 base::ListValue* url_list = update.Get();
375 url_list->Append(base::Value::CreateStringValue(example_url0_));
376 url_list->Append(base::Value::CreateStringValue(example_url1_));
379 PreferenceValues cloud_data;
380 STLValueDeleter<PreferenceValues> cloud_data_deleter(&cloud_data);
381 cloud_data[prefs::kHomePage] = base::Value::CreateStringValue(example_url1_);
382 base::ListValue* urls_to_restore = new base::ListValue;
383 urls_to_restore->Append(base::Value::CreateStringValue(example_url1_));
384 urls_to_restore->Append(base::Value::CreateStringValue(example_url2_));
385 cloud_data[prefs::kURLsToRestoreOnStartup] = urls_to_restore;
386 cloud_data[prefs::kDefaultCharset] =
387 base::Value::CreateStringValue(non_default_charset_value_);
389 AddPreferenceEntriesHelper helper(this, cloud_data);
390 ASSERT_TRUE(StartSyncService(helper.callback(), false));
391 ASSERT_TRUE(helper.success());
393 scoped_ptr<const base::Value> value(GetSyncedValue(prefs::kHomePage));
394 ASSERT_TRUE(value.get());
395 std::string string_value;
396 EXPECT_TRUE(value->GetAsString(&string_value));
397 EXPECT_EQ(example_url1_, string_value);
398 EXPECT_EQ(example_url1_, prefs_->GetString(prefs::kHomePage));
400 scoped_ptr<base::ListValue> expected_urls(new base::ListValue);
401 expected_urls->Append(base::Value::CreateStringValue(example_url1_));
402 expected_urls->Append(base::Value::CreateStringValue(example_url2_));
403 expected_urls->Append(base::Value::CreateStringValue(example_url0_));
404 value.reset(GetSyncedValue(prefs::kURLsToRestoreOnStartup));
405 ASSERT_TRUE(value.get());
406 EXPECT_TRUE(value->Equals(expected_urls.get()));
407 EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartup).
408 Equals(expected_urls.get()));
410 value.reset(GetSyncedValue(prefs::kDefaultCharset));
411 ASSERT_TRUE(value.get());
412 EXPECT_TRUE(value->GetAsString(&string_value));
413 EXPECT_EQ(non_default_charset_value_, string_value);
414 EXPECT_EQ(non_default_charset_value_,
415 prefs_->GetString(prefs::kDefaultCharset));
418 TEST_F(ProfileSyncServicePreferenceTest, ModelAssociationMigrateOldData) {
419 ASSERT_TRUE(IsMigratedPreference(prefs::kURLsToRestoreOnStartup));
420 ASSERT_TRUE(IsOldMigratedPreference(prefs::kURLsToRestoreOnStartupOld));
422 PreferenceValues cloud_data;
423 STLValueDeleter<PreferenceValues> cloud_data_deleter(&cloud_data);
424 base::ListValue* urls_to_restore = new base::ListValue;
425 urls_to_restore->Append(base::Value::CreateStringValue(example_url1_));
426 urls_to_restore->Append(base::Value::CreateStringValue(example_url2_));
427 cloud_data[prefs::kURLsToRestoreOnStartupOld] = urls_to_restore;
429 AddPreferenceEntriesHelper helper(this, cloud_data);
430 ASSERT_TRUE(StartSyncService(helper.callback(), false));
431 ASSERT_TRUE(helper.success());
433 // Expect that the new preference data contains the old pref's values.
434 scoped_ptr<base::ListValue> expected_urls(new base::ListValue);
435 expected_urls->Append(base::Value::CreateStringValue(example_url1_));
436 expected_urls->Append(base::Value::CreateStringValue(example_url2_));
438 ASSERT_TRUE(HasSyncData(prefs::kURLsToRestoreOnStartup));
439 scoped_ptr<const base::Value> value(
440 GetSyncedValue(prefs::kURLsToRestoreOnStartup));
441 ASSERT_TRUE(value.get());
442 EXPECT_TRUE(value->Equals(expected_urls.get()));
443 EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartup).
444 Equals(expected_urls.get()));
446 // The old preference value should be the same.
447 expected_urls.reset(new base::ListValue);
448 value.reset(GetSyncedValue(prefs::kURLsToRestoreOnStartupOld));
449 ASSERT_TRUE(value.get());
450 EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartupOld).
451 Equals(expected_urls.get()));
454 TEST_F(ProfileSyncServicePreferenceTest,
455 ModelAssociationCloudHasOldMigratedData) {
456 ASSERT_TRUE(IsMigratedPreference(prefs::kURLsToRestoreOnStartup));
457 ASSERT_TRUE(IsOldMigratedPreference(prefs::kURLsToRestoreOnStartupOld));
458 prefs_->SetString(prefs::kHomePage, example_url0_);
460 ListPrefUpdate update(prefs_, prefs::kURLsToRestoreOnStartup);
461 base::ListValue* url_list = update.Get();
462 url_list->Append(base::Value::CreateStringValue(example_url0_));
463 url_list->Append(base::Value::CreateStringValue(example_url1_));
466 PreferenceValues cloud_data;
467 STLValueDeleter<PreferenceValues> cloud_data_deleter(&cloud_data);
468 cloud_data[prefs::kHomePage] = base::Value::CreateStringValue(example_url1_);
469 base::ListValue* urls_to_restore = new base::ListValue;
470 urls_to_restore->Append(base::Value::CreateStringValue(example_url1_));
471 urls_to_restore->Append(base::Value::CreateStringValue(example_url2_));
472 cloud_data[prefs::kURLsToRestoreOnStartupOld] = urls_to_restore;
474 AddPreferenceEntriesHelper helper(this, cloud_data);
475 ASSERT_TRUE(StartSyncService(helper.callback(), false));
476 ASSERT_TRUE(helper.success());
478 scoped_ptr<const base::Value> value(GetSyncedValue(prefs::kHomePage));
479 ASSERT_TRUE(value.get());
480 std::string string_value;
481 EXPECT_TRUE(value->GetAsString(&string_value));
482 EXPECT_EQ(example_url1_, string_value);
483 EXPECT_EQ(example_url1_, prefs_->GetString(prefs::kHomePage));
485 // Expect that the new preference data contains the merged old prefs values.
486 scoped_ptr<base::ListValue> expected_urls(new base::ListValue);
487 expected_urls->Append(base::Value::CreateStringValue(example_url1_));
488 expected_urls->Append(base::Value::CreateStringValue(example_url2_));
489 expected_urls->Append(base::Value::CreateStringValue(example_url0_));
491 ASSERT_TRUE(HasSyncData(prefs::kURLsToRestoreOnStartup));
492 value.reset(GetSyncedValue(prefs::kURLsToRestoreOnStartup));
493 ASSERT_TRUE(value.get());
494 EXPECT_TRUE(value->Equals(expected_urls.get()));
495 EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartup).
496 Equals(expected_urls.get()));
498 // The old preference name should also contain the merged sync data.
499 expected_urls.reset(new base::ListValue);
500 value.reset(GetSyncedValue(prefs::kURLsToRestoreOnStartupOld));
501 ASSERT_TRUE(value.get());
502 EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartupOld).
503 Equals(expected_urls.get()));
506 TEST_F(ProfileSyncServicePreferenceTest,
507 ModelAssociationCloudHasNewMigratedData) {
508 ASSERT_TRUE(IsMigratedPreference(prefs::kURLsToRestoreOnStartup));
509 ASSERT_TRUE(IsOldMigratedPreference(prefs::kURLsToRestoreOnStartupOld));
510 prefs_->SetString(prefs::kHomePage, example_url0_);
512 ListPrefUpdate update(prefs_, prefs::kURLsToRestoreOnStartupOld);
513 base::ListValue* url_list = update.Get();
514 url_list->Append(base::Value::CreateStringValue(example_url0_));
515 url_list->Append(base::Value::CreateStringValue(example_url1_));
518 PreferenceValues cloud_data;
519 STLValueDeleter<PreferenceValues> cloud_data_deleter(&cloud_data);
520 cloud_data[prefs::kHomePage] = base::Value::CreateStringValue(example_url1_);
521 base::ListValue* urls_to_restore = new base::ListValue;
522 urls_to_restore->Append(base::Value::CreateStringValue(example_url1_));
523 urls_to_restore->Append(base::Value::CreateStringValue(example_url2_));
524 cloud_data[prefs::kURLsToRestoreOnStartup] = urls_to_restore;
526 AddPreferenceEntriesHelper helper(this, cloud_data);
527 ASSERT_TRUE(StartSyncService(helper.callback(), false));
528 ASSERT_TRUE(helper.success());
530 scoped_ptr<const base::Value> value(GetSyncedValue(prefs::kHomePage));
531 ASSERT_TRUE(value.get());
532 std::string string_value;
533 EXPECT_TRUE(value->GetAsString(&string_value));
534 EXPECT_EQ(example_url1_, string_value);
535 EXPECT_EQ(example_url1_, prefs_->GetString(prefs::kHomePage));
537 // Expect that the cloud data under the new migrated preference name sticks.
538 scoped_ptr<base::ListValue> expected_urls(new base::ListValue);
539 expected_urls->Append(base::Value::CreateStringValue(example_url1_));
540 expected_urls->Append(base::Value::CreateStringValue(example_url2_));
542 ASSERT_TRUE(HasSyncData(prefs::kURLsToRestoreOnStartup));
543 value.reset(GetSyncedValue(prefs::kURLsToRestoreOnStartup));
544 ASSERT_TRUE(value.get());
545 EXPECT_TRUE(value->Equals(expected_urls.get()));
546 EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartup).
547 Equals(expected_urls.get()));
549 // The old preference data should still be here, though not synced.
550 expected_urls.reset(new base::ListValue);
551 expected_urls->Append(base::Value::CreateStringValue(example_url0_));
552 expected_urls->Append(base::Value::CreateStringValue(example_url1_));
554 value.reset(GetSyncedValue(prefs::kURLsToRestoreOnStartupOld));
555 ASSERT_FALSE(value.get());
556 EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartupOld).
557 Equals(expected_urls.get()));
560 TEST_F(ProfileSyncServicePreferenceTest,
561 ModelAssociationCloudAddsOldAndNewMigratedData) {
562 ASSERT_TRUE(IsMigratedPreference(prefs::kURLsToRestoreOnStartup));
563 ASSERT_TRUE(IsOldMigratedPreference(prefs::kURLsToRestoreOnStartupOld));
564 prefs_->SetString(prefs::kHomePage, example_url0_);
566 ListPrefUpdate update_old(prefs_, prefs::kURLsToRestoreOnStartupOld);
567 base::ListValue* url_list_old = update_old.Get();
568 url_list_old->Append(base::Value::CreateStringValue(example_url0_));
569 url_list_old->Append(base::Value::CreateStringValue(example_url1_));
570 ListPrefUpdate update(prefs_, prefs::kURLsToRestoreOnStartup);
571 base::ListValue* url_list = update.Get();
572 url_list->Append(base::Value::CreateStringValue(example_url1_));
573 url_list->Append(base::Value::CreateStringValue(example_url2_));
576 PreferenceValues cloud_data;
577 STLValueDeleter<PreferenceValues> cloud_data_deleter(&cloud_data);
578 cloud_data[prefs::kHomePage] = base::Value::CreateStringValue(example_url1_);
580 AddPreferenceEntriesHelper helper(this, cloud_data);
581 ASSERT_TRUE(StartSyncService(helper.callback(), false));
582 ASSERT_TRUE(helper.success());
584 scoped_ptr<const base::Value> value(GetSyncedValue(prefs::kHomePage));
585 ASSERT_TRUE(value.get());
586 std::string string_value;
587 EXPECT_TRUE(value->GetAsString(&string_value));
588 EXPECT_EQ(example_url1_, string_value);
589 EXPECT_EQ(example_url1_, prefs_->GetString(prefs::kHomePage));
591 // Expect that the cloud data under the new migrated preference name sticks.
592 scoped_ptr<base::ListValue> expected_urls(new base::ListValue);
593 expected_urls->Append(base::Value::CreateStringValue(example_url1_));
594 expected_urls->Append(base::Value::CreateStringValue(example_url2_));
596 ASSERT_TRUE(HasSyncData(prefs::kURLsToRestoreOnStartup));
597 value.reset(GetSyncedValue(prefs::kURLsToRestoreOnStartup));
598 ASSERT_TRUE(value.get());
599 EXPECT_TRUE(value->Equals(expected_urls.get()));
600 EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartup).
601 Equals(expected_urls.get()));
603 // Should not have synced in the old startup url values.
604 value.reset(GetSyncedValue(prefs::kURLsToRestoreOnStartupOld));
605 ASSERT_FALSE(value.get());
606 EXPECT_FALSE(GetPreferenceValue(prefs::kURLsToRestoreOnStartupOld).
607 Equals(expected_urls.get()));
610 TEST_F(ProfileSyncServicePreferenceTest, FailModelAssociation) {
611 ASSERT_TRUE(StartSyncService(base::Closure(), true));
612 EXPECT_TRUE(sync_service_->HasUnrecoverableError());
615 TEST_F(ProfileSyncServicePreferenceTest, UpdatedPreferenceWithDefaultValue) {
616 const PrefService::Preference* pref =
617 prefs_->FindPreference(prefs::kHomePage);
618 EXPECT_TRUE(pref->IsDefaultValue());
620 CreateRootHelper create_root(this, syncer::PREFERENCES);
621 ASSERT_TRUE(StartSyncService(create_root.callback(), false));
622 ASSERT_TRUE(create_root.success());
624 scoped_ptr<base::Value> expected(
625 base::Value::CreateStringValue(example_url0_));
626 profile_->GetPrefs()->Set(prefs::kHomePage, *expected);
628 scoped_ptr<const base::Value> actual(GetSyncedValue(prefs::kHomePage));
629 ASSERT_TRUE(actual.get());
630 EXPECT_TRUE(expected->Equals(actual.get()));
633 TEST_F(ProfileSyncServicePreferenceTest, UpdatedPreferenceWithValue) {
634 profile_->GetPrefs()->SetString(prefs::kHomePage, example_url0_);
635 CreateRootHelper create_root(this, syncer::PREFERENCES);
636 ASSERT_TRUE(StartSyncService(create_root.callback(), false));
637 ASSERT_TRUE(create_root.success());
639 scoped_ptr<base::Value> expected(
640 base::Value::CreateStringValue(example_url1_));
641 profile_->GetPrefs()->Set(prefs::kHomePage, *expected);
643 scoped_ptr<const base::Value> actual(GetSyncedValue(prefs::kHomePage));
644 ASSERT_TRUE(actual.get());
645 EXPECT_TRUE(expected->Equals(actual.get()));
648 TEST_F(ProfileSyncServicePreferenceTest, UpdatedSyncNodeActionUpdate) {
649 profile_->GetPrefs()->SetString(prefs::kHomePage, example_url0_);
650 CreateRootHelper create_root(this, syncer::PREFERENCES);
651 ASSERT_TRUE(StartSyncService(create_root.callback(), false));
652 ASSERT_TRUE(create_root.success());
654 scoped_ptr<base::Value> expected(
655 base::Value::CreateStringValue(example_url1_));
656 int64 node_id = SetSyncedValue(prefs::kHomePage, *expected);
657 ASSERT_NE(node_id, syncer::kInvalidId);
659 syncer::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare());
660 change_processor_->ApplyChangesFromSyncModel(
661 &trans, 0,
662 ProfileSyncServiceTestHelper::MakeSingletonChangeRecordList(
663 node_id, ChangeRecord::ACTION_UPDATE));
665 change_processor_->CommitChangesFromSyncModel();
667 const base::Value& actual = GetPreferenceValue(prefs::kHomePage);
668 EXPECT_TRUE(expected->Equals(&actual));
671 TEST_F(ProfileSyncServicePreferenceTest, UpdatedSyncNodeActionAdd) {
672 CreateRootHelper create_root(this, syncer::PREFERENCES);
673 ASSERT_TRUE(StartSyncService(create_root.callback(), false));
674 ASSERT_TRUE(create_root.success());
676 scoped_ptr<base::Value> expected(
677 base::Value::CreateStringValue(example_url0_));
678 int64 node_id = SetSyncedValue(prefs::kHomePage, *expected);
679 ASSERT_NE(node_id, syncer::kInvalidId);
681 syncer::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare());
682 change_processor_->ApplyChangesFromSyncModel(
683 &trans, 0,
684 ProfileSyncServiceTestHelper::MakeSingletonChangeRecordList(
685 node_id, ChangeRecord::ACTION_ADD));
687 change_processor_->CommitChangesFromSyncModel();
689 const base::Value& actual = GetPreferenceValue(prefs::kHomePage);
690 EXPECT_TRUE(expected->Equals(&actual));
691 EXPECT_EQ(1U,
692 pref_sync_service_->registered_preferences().count(prefs::kHomePage));
695 TEST_F(ProfileSyncServicePreferenceTest, UpdatedSyncNodeUnknownPreference) {
696 CreateRootHelper create_root(this, syncer::PREFERENCES);
697 ASSERT_TRUE(StartSyncService(create_root.callback(), false));
698 ASSERT_TRUE(create_root.success());
700 scoped_ptr<base::Value> expected(
701 base::Value::CreateStringValue(example_url0_));
702 int64 node_id = SetSyncedValue("unknown preference", *expected);
703 ASSERT_NE(node_id, syncer::kInvalidId);
705 syncer::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare());
706 change_processor_->ApplyChangesFromSyncModel(
707 &trans, 0,
708 ProfileSyncServiceTestHelper::MakeSingletonChangeRecordList(
709 node_id, ChangeRecord::ACTION_UPDATE));
711 change_processor_->CommitChangesFromSyncModel();
713 // Nothing interesting happens on the client when it gets an update
714 // of an unknown preference. We just should not crash.
717 TEST_F(ProfileSyncServicePreferenceTest, ManagedPreferences) {
718 // Make the homepage preference managed.
719 scoped_ptr<base::Value> managed_value(
720 base::Value::CreateStringValue("http://example.com"));
721 prefs_->SetManagedPref(prefs::kHomePage, managed_value->DeepCopy());
723 CreateRootHelper create_root(this, syncer::PREFERENCES);
724 ASSERT_TRUE(StartSyncService(create_root.callback(), false));
725 ASSERT_TRUE(create_root.success());
727 // Changing the homepage preference should not sync anything.
728 scoped_ptr<base::Value> user_value(
729 base::Value::CreateStringValue("http://chromium..com"));
730 prefs_->SetUserPref(prefs::kHomePage, user_value->DeepCopy());
731 EXPECT_EQ(NULL, GetSyncedValue(prefs::kHomePage));
733 // An incoming sync transaction should change the user value, not the managed
734 // value.
735 scoped_ptr<base::Value> sync_value(
736 base::Value::CreateStringValue("http://crbug.com"));
737 int64 node_id = SetSyncedValue(prefs::kHomePage, *sync_value);
738 ASSERT_NE(node_id, syncer::kInvalidId);
740 syncer::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare());
741 change_processor_->ApplyChangesFromSyncModel(
742 &trans, 0,
743 ProfileSyncServiceTestHelper::MakeSingletonChangeRecordList(
744 node_id, ChangeRecord::ACTION_UPDATE));
746 change_processor_->CommitChangesFromSyncModel();
748 EXPECT_TRUE(managed_value->Equals(prefs_->GetManagedPref(prefs::kHomePage)));
749 EXPECT_TRUE(sync_value->Equals(prefs_->GetUserPref(prefs::kHomePage)));
752 // List preferences have special handling at association time due to our ability
753 // to merge the local and sync value. Make sure the merge logic doesn't merge
754 // managed preferences.
755 TEST_F(ProfileSyncServicePreferenceTest, ManagedListPreferences) {
756 // Make the list of urls to restore on startup managed.
757 base::ListValue managed_value;
758 managed_value.Append(base::Value::CreateStringValue(example_url0_));
759 managed_value.Append(base::Value::CreateStringValue(example_url1_));
760 prefs_->SetManagedPref(prefs::kURLsToRestoreOnStartup,
761 managed_value.DeepCopy());
763 // Set a cloud version.
764 PreferenceValues cloud_data;
765 STLValueDeleter<PreferenceValues> cloud_data_deleter(&cloud_data);
766 base::ListValue* urls_to_restore = new base::ListValue;
767 urls_to_restore->Append(base::Value::CreateStringValue(example_url1_));
768 urls_to_restore->Append(base::Value::CreateStringValue(example_url2_));
769 cloud_data[prefs::kURLsToRestoreOnStartup] = urls_to_restore;
771 // Start sync and verify the synced value didn't get merged.
772 AddPreferenceEntriesHelper helper(this, cloud_data);
773 ASSERT_TRUE(StartSyncService(helper.callback(), false));
774 ASSERT_TRUE(helper.success());
775 scoped_ptr<const base::Value> actual(
776 GetSyncedValue(prefs::kURLsToRestoreOnStartup));
777 EXPECT_TRUE(cloud_data[prefs::kURLsToRestoreOnStartup]->Equals(actual.get()));
779 // Changing the user's urls to restore on startup pref should not sync
780 // anything.
781 base::ListValue user_value;
782 user_value.Append(base::Value::CreateStringValue("http://chromium.org"));
783 prefs_->SetUserPref(prefs::kURLsToRestoreOnStartup, user_value.DeepCopy());
784 actual.reset(GetSyncedValue(prefs::kURLsToRestoreOnStartup));
785 EXPECT_TRUE(cloud_data[prefs::kURLsToRestoreOnStartup]->Equals(actual.get()));
787 // An incoming sync transaction should change the user value, not the managed
788 // value.
789 base::ListValue sync_value;
790 sync_value.Append(base::Value::CreateStringValue("http://crbug.com"));
791 int64 node_id = SetSyncedValue(prefs::kURLsToRestoreOnStartup, sync_value);
792 ASSERT_NE(node_id, syncer::kInvalidId);
794 syncer::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare());
795 change_processor_->ApplyChangesFromSyncModel(
796 &trans, 0,
797 ProfileSyncServiceTestHelper::MakeSingletonChangeRecordList(
798 node_id, ChangeRecord::ACTION_UPDATE));
800 change_processor_->CommitChangesFromSyncModel();
802 EXPECT_TRUE(managed_value.Equals(
803 prefs_->GetManagedPref(prefs::kURLsToRestoreOnStartup)));
804 EXPECT_TRUE(sync_value.Equals(
805 prefs_->GetUserPref(prefs::kURLsToRestoreOnStartup)));
808 TEST_F(ProfileSyncServicePreferenceTest, DynamicManagedPreferences) {
809 CreateRootHelper create_root(this, syncer::PREFERENCES);
810 ASSERT_TRUE(StartSyncService(create_root.callback(), false));
811 ASSERT_TRUE(create_root.success());
813 scoped_ptr<base::Value> initial_value(
814 base::Value::CreateStringValue("http://example.com/initial"));
815 profile_->GetPrefs()->Set(prefs::kHomePage, *initial_value);
816 scoped_ptr<const base::Value> actual(GetSyncedValue(prefs::kHomePage));
817 ASSERT_TRUE(actual.get());
818 EXPECT_TRUE(initial_value->Equals(actual.get()));
820 // Switch kHomePage to managed and set a different value.
821 scoped_ptr<base::Value> managed_value(
822 base::Value::CreateStringValue("http://example.com/managed"));
823 profile_->GetTestingPrefService()->SetManagedPref(
824 prefs::kHomePage, managed_value->DeepCopy());
826 // The pref value should be the one dictated by policy.
827 EXPECT_TRUE(managed_value->Equals(&GetPreferenceValue(prefs::kHomePage)));
829 // Switch kHomePage back to unmanaged.
830 profile_->GetTestingPrefService()->RemoveManagedPref(prefs::kHomePage);
832 // The original value should be picked up.
833 EXPECT_TRUE(initial_value->Equals(&GetPreferenceValue(prefs::kHomePage)));
836 TEST_F(ProfileSyncServicePreferenceTest,
837 DynamicManagedPreferencesWithSyncChange) {
838 CreateRootHelper create_root(this, syncer::PREFERENCES);
839 ASSERT_TRUE(StartSyncService(create_root.callback(), false));
840 ASSERT_TRUE(create_root.success());
842 scoped_ptr<base::Value> initial_value(
843 base::Value::CreateStringValue("http://example.com/initial"));
844 profile_->GetPrefs()->Set(prefs::kHomePage, *initial_value);
845 scoped_ptr<const base::Value> actual(GetSyncedValue(prefs::kHomePage));
846 EXPECT_TRUE(initial_value->Equals(actual.get()));
848 // Switch kHomePage to managed and set a different value.
849 scoped_ptr<base::Value> managed_value(
850 base::Value::CreateStringValue("http://example.com/managed"));
851 profile_->GetTestingPrefService()->SetManagedPref(
852 prefs::kHomePage, managed_value->DeepCopy());
854 // Change the sync value.
855 scoped_ptr<base::Value> sync_value(
856 base::Value::CreateStringValue("http://example.com/sync"));
857 int64 node_id = SetSyncedValue(prefs::kHomePage, *sync_value);
858 ASSERT_NE(node_id, syncer::kInvalidId);
860 syncer::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare());
861 change_processor_->ApplyChangesFromSyncModel(
862 &trans, 0,
863 ProfileSyncServiceTestHelper::MakeSingletonChangeRecordList(
864 node_id, ChangeRecord::ACTION_ADD));
866 change_processor_->CommitChangesFromSyncModel();
868 // The pref value should still be the one dictated by policy.
869 EXPECT_TRUE(managed_value->Equals(&GetPreferenceValue(prefs::kHomePage)));
871 // Switch kHomePage back to unmanaged.
872 profile_->GetTestingPrefService()->RemoveManagedPref(prefs::kHomePage);
874 // Sync value should be picked up.
875 EXPECT_TRUE(sync_value->Equals(&GetPreferenceValue(prefs::kHomePage)));
878 TEST_F(ProfileSyncServicePreferenceTest, DynamicManagedDefaultPreferences) {
879 const PrefService::Preference* pref =
880 prefs_->FindPreference(prefs::kHomePage);
881 EXPECT_TRUE(pref->IsDefaultValue());
882 CreateRootHelper create_root(this, syncer::PREFERENCES);
883 ASSERT_TRUE(StartSyncService(create_root.callback(), false));
884 ASSERT_TRUE(create_root.success());
885 EXPECT_TRUE(IsSynced(prefs::kHomePage));
886 EXPECT_TRUE(pref->IsDefaultValue());
887 EXPECT_TRUE(GetSyncedValue(prefs::kHomePage) == NULL);
888 // Switch kHomePage to managed and set a different value.
889 scoped_ptr<base::Value> managed_value(
890 base::Value::CreateStringValue("http://example.com/managed"));
891 profile_->GetTestingPrefService()->SetManagedPref(
892 prefs::kHomePage, managed_value->DeepCopy());
893 // The pref value should be the one dictated by policy.
894 EXPECT_TRUE(managed_value->Equals(&GetPreferenceValue(prefs::kHomePage)));
895 EXPECT_FALSE(pref->IsDefaultValue());
896 // There should be no synced value.
897 EXPECT_TRUE(GetSyncedValue(prefs::kHomePage) == NULL);
898 // Switch kHomePage back to unmanaged.
899 profile_->GetTestingPrefService()->RemoveManagedPref(prefs::kHomePage);
900 // The original value should be picked up.
901 EXPECT_TRUE(pref->IsDefaultValue());
902 // There should still be no synced value.
903 EXPECT_TRUE(GetSyncedValue(prefs::kHomePage) == NULL);