1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <map>
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string>
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/json/json_reader.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/stl_util-inl.h"
103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_piece.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/task.h"
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/prefs/scoped_user_pref_update.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/abstract_profile_sync_service_test.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/engine/syncapi.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/glue/preference_change_processor.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/glue/preference_data_type_controller.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/glue/preference_model_associator.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/glue/sync_backend_host.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/profile_sync_test_util.h"
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/protocol/preference_specifics.pb.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/syncable/model_type.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/test_profile_sync_service.h"
233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/net/gaia/gaia_constants.h"
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/pref_names.h"
253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/test/testing_pref_service.h"
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/test/testing_profile.h"
27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/json_value_serializer.h"
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gmock/include/gmock/gmock.h"
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gtest/include/gtest/gtest.h"
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::JSONReader;
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing browser_sync::PreferenceChangeProcessor;
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing browser_sync::PreferenceDataTypeController;
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing browser_sync::PreferenceModelAssociator;
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing browser_sync::SyncBackendHost;
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing sync_api::SyncManager;
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing testing::_;
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing testing::Return;
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merricktypedef std::map<const std::string, const Value*> PreferenceValues;
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ProfileSyncServicePreferenceTest
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : public AbstractProfileSyncServiceTest {
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected:
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ProfileSyncServicePreferenceTest()
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : example_url0_("http://example.com/0"),
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        example_url1_("http://example.com/1"),
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        example_url2_("http://example.com/2"),
493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        not_synced_preference_name_("nonsense_pref_name"),
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        not_synced_preference_default_value_("default"),
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        non_default_charset_value_("foo") {}
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void SetUp() {
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    profile_.reset(new TestingProfile());
55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    profile_->CreateRequestContext();
563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    prefs_ = profile_->GetTestingPrefService();
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    prefs_->RegisterStringPref(not_synced_preference_name_.c_str(),
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               not_synced_preference_default_value_);
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void TearDown() {
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    service_.reset();
64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    {
65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // The request context gets deleted on the I/O thread. To prevent a leak
66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // supply one here.
67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      BrowserThread io_thread(BrowserThread::IO, MessageLoop::current());
68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      profile_.reset();
69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop::current()->RunAllPending();
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool StartSyncService(Task* task, bool will_fail_association) {
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (service_.get())
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return false;
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    service_.reset(new TestProfileSyncService(
783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        &factory_, profile_.get(), "test", false, task));
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Register the preference data type.
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    model_associator_ =
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        new PreferenceModelAssociator(service_.get());
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    change_processor_ = new PreferenceChangeProcessor(model_associator_,
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                      service_.get());
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_CALL(factory_, CreatePreferenceSyncComponents(_, _)).
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        WillOnce(Return(ProfileSyncFactory::SyncComponents(
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            model_associator_, change_processor_)));
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_CALL(factory_, CreateDataTypeManager(_, _)).
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        WillOnce(ReturnNewDataTypeManager());
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    service_->RegisterDataTypeController(
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        new PreferenceDataTypeController(&factory_,
94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                         profile_.get(),
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         service_.get()));
963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    profile_->GetTokenService()->IssueAuthTokenForTest(
973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        GaiaConstants::kSyncService, "token");
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    service_->Initialize();
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop::current()->Run();
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const Value& GetPreferenceValue(const std::string& name) {
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const PrefService::Preference* preference =
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        prefs_->FindPreference(name.c_str());
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return *preference->GetValue();
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Caller gets ownership of the returned value.
1103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const Value* GetSyncedValue(const std::string& name) {
11172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    sync_api::ReadTransaction trans(service_->GetUserShare());
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    sync_api::ReadNode node(&trans);
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int64 node_id = model_associator_->GetSyncIdFromChromeId(name);
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (node_id == sync_api::kInvalidId)
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return NULL;
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!node.InitByIdLookup(node_id))
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return NULL;
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const sync_pb::PreferenceSpecifics& specifics(
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        node.GetPreferenceSpecifics());
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    JSONReader reader;
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return reader.JsonToValue(specifics.value(), false, false);
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  int64 WriteSyncedValue(const std::string& name,
128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                         const Value& value,
129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                         sync_api::WriteNode* node) {
130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!PreferenceModelAssociator::WritePreferenceToNode(name, value, node))
1313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      return sync_api::kInvalidId;
132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return node->GetId();
1333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
1343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int64 SetSyncedValue(const std::string& name, const Value& value) {
13672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    sync_api::WriteTransaction trans(service_->GetUserShare());
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    sync_api::ReadNode root(&trans);
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!root.InitByTagLookup(browser_sync::kPreferencesTag))
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return sync_api::kInvalidId;
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    sync_api::WriteNode tag_node(&trans);
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    sync_api::WriteNode node(&trans);
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int64 node_id = model_associator_->GetSyncIdFromChromeId(name);
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (node_id == sync_api::kInvalidId) {
1463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      if (tag_node.InitByClientTagLookup(syncable::PREFERENCES, name))
147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        return WriteSyncedValue(name, value, &tag_node);
1483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      if (node.InitUniqueByCreation(syncable::PREFERENCES, root, name))
149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        return WriteSyncedValue(name, value, &node);
1503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    } else if (node.InitByIdLookup(node_id)) {
151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return WriteSyncedValue(name, value, &node);
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return sync_api::kInvalidId;
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  SyncManager::ChangeRecord* MakeChangeRecord(const std::string& name,
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                              SyncManager::ChangeRecord) {
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int64 node_id = model_associator_->GetSyncIdFromChromeId(name);
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SyncManager::ChangeRecord* record = new SyncManager::ChangeRecord();
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    record->action = SyncManager::ChangeRecord::ACTION_UPDATE;
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    record->id = node_id;
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return record;
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool IsSynced(const std::string& pref_name) {
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return model_associator_->synced_preferences().count(pref_name) > 0;
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string ValueString(const Value& value) {
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string serialized;
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    JSONStringValueSerializer json(&serialized);
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    json.Serialize(value);
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return serialized;
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  friend class AddPreferenceEntriesTask;
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<TestingProfile> profile_;
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestingPrefService* prefs_;
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  PreferenceModelAssociator* model_associator_;
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  PreferenceChangeProcessor* change_processor_;
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string example_url0_;
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string example_url1_;
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string example_url2_;
1863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string not_synced_preference_name_;
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string not_synced_preference_default_value_;
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string non_default_charset_value_;
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass AddPreferenceEntriesTask : public Task {
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddPreferenceEntriesTask(ProfileSyncServicePreferenceTest* test,
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           const PreferenceValues& entries)
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : test_(test), entries_(entries), success_(false) {
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void Run() {
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!test_->CreateRoot(syncable::PREFERENCES))
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return;
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (PreferenceValues::const_iterator i = entries_.begin();
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         i != entries_.end(); ++i) {
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (test_->SetSyncedValue(i->first, *i->second) == sync_api::kInvalidId)
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        return;
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    success_ = true;
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool success() { return success_; }
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ProfileSyncServicePreferenceTest* test_;
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const PreferenceValues& entries_;
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool success_;
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ProfileSyncServicePreferenceTest, WritePreferenceToNode) {
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  prefs_->SetString(prefs::kHomePage, example_url0_);
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreateRootTask task(this, syncable::PREFERENCES);
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(StartSyncService(&task, false));
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(task.success());
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const PrefService::Preference* pref =
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      prefs_->FindPreference(prefs::kHomePage);
22572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  sync_api::WriteTransaction trans(service_->GetUserShare());
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  sync_api::WriteNode node(&trans);
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(node.InitByClientTagLookup(syncable::PREFERENCES,
2283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                         prefs::kHomePage));
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(PreferenceModelAssociator::WritePreferenceToNode(
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      pref->name(), *pref->GetValue(), &node));
2323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(UTF8ToWide(prefs::kHomePage), node.GetTitle());
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const sync_pb::PreferenceSpecifics& specifics(node.GetPreferenceSpecifics());
2343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(std::string(prefs::kHomePage), specifics.name());
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base::JSONReader reader;
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<Value> value(reader.JsonToValue(specifics.value(), false, false));
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(pref->GetValue()->Equals(value.get()));
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ProfileSyncServicePreferenceTest, ModelAssociationDoNotSyncDefaults) {
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const PrefService::Preference* pref =
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      prefs_->FindPreference(prefs::kHomePage);
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(pref->IsDefaultValue());
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreateRootTask task(this, syncable::PREFERENCES);
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(StartSyncService(&task, false));
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(task.success());
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(IsSynced(prefs::kHomePage));
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(pref->IsDefaultValue());
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(GetSyncedValue(prefs::kHomePage) == NULL);
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(GetSyncedValue(not_synced_preference_name_) == NULL);
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ProfileSyncServicePreferenceTest, ModelAssociationEmptyCloud) {
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  prefs_->SetString(prefs::kHomePage, example_url0_);
256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  {
257ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ListPrefUpdate update(prefs_, prefs::kURLsToRestoreOnStartup);
258ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ListValue* url_list = update.Get();
259ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    url_list->Append(Value::CreateStringValue(example_url0_));
260ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    url_list->Append(Value::CreateStringValue(example_url1_));
261ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreateRootTask task(this, syncable::PREFERENCES);
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(StartSyncService(&task, false));
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(task.success());
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<const Value> value(GetSyncedValue(prefs::kHomePage));
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(value.get());
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(GetPreferenceValue(prefs::kHomePage).Equals(value.get()));
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  value.reset(GetSyncedValue(prefs::kURLsToRestoreOnStartup));
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(value.get());
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GetPreferenceValue(prefs::kURLsToRestoreOnStartup).Equals(value.get()));
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ProfileSyncServicePreferenceTest, ModelAssociationCloudHasData) {
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  prefs_->SetString(prefs::kHomePage, example_url0_);
277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  {
278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ListPrefUpdate update(prefs_, prefs::kURLsToRestoreOnStartup);
279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ListValue* url_list = update.Get();
280ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    url_list->Append(Value::CreateStringValue(example_url0_));
281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    url_list->Append(Value::CreateStringValue(example_url1_));
282ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  PreferenceValues cloud_data;
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cloud_data[prefs::kHomePage] = Value::CreateStringValue(example_url1_);
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue* urls_to_restore = new ListValue;
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  urls_to_restore->Append(Value::CreateStringValue(example_url1_));
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  urls_to_restore->Append(Value::CreateStringValue(example_url2_));
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cloud_data[prefs::kURLsToRestoreOnStartup] = urls_to_restore;
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cloud_data[prefs::kDefaultCharset] =
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      Value::CreateStringValue(non_default_charset_value_);
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddPreferenceEntriesTask task(this, cloud_data);
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(StartSyncService(&task, false));
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(task.success());
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<const Value> value(GetSyncedValue(prefs::kHomePage));
298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(value.get());
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string string_value;
300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(static_cast<const StringValue*>(value.get())->
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              GetAsString(&string_value));
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(example_url1_, string_value);
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(example_url1_, prefs_->GetString(prefs::kHomePage));
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<ListValue> expected_urls(new ListValue);
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  expected_urls->Append(Value::CreateStringValue(example_url1_));
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  expected_urls->Append(Value::CreateStringValue(example_url2_));
308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  expected_urls->Append(Value::CreateStringValue(example_url0_));
309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  value.reset(GetSyncedValue(prefs::kURLsToRestoreOnStartup));
310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(value.get());
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(value->Equals(expected_urls.get()));
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartup).
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              Equals(expected_urls.get()));
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  value.reset(GetSyncedValue(prefs::kDefaultCharset));
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(value.get());
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(static_cast<const StringValue*>(value.get())->
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              GetAsString(&string_value));
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(non_default_charset_value_, string_value);
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(non_default_charset_value_,
321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            prefs_->GetString(prefs::kDefaultCharset));
322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  STLDeleteValues(&cloud_data);
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ProfileSyncServicePreferenceTest, FailModelAssociation) {
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(StartSyncService(NULL, true));
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(service_->unrecoverable_error_detected());
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ProfileSyncServicePreferenceTest, UpdatedPreferenceWithDefaultValue) {
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const PrefService::Preference* pref =
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      prefs_->FindPreference(prefs::kHomePage);
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(pref->IsDefaultValue());
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreateRootTask task(this, syncable::PREFERENCES);
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(StartSyncService(&task, false));
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(task.success());
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<Value> expected(Value::CreateStringValue(example_url0_));
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  profile_->GetPrefs()->Set(prefs::kHomePage, *expected);
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<const Value> actual(GetSyncedValue(prefs::kHomePage));
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(actual.get());
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(expected->Equals(actual.get()));
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ProfileSyncServicePreferenceTest, UpdatedPreferenceWithValue) {
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  profile_->GetPrefs()->SetString(prefs::kHomePage, example_url0_);
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreateRootTask task(this, syncable::PREFERENCES);
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(StartSyncService(&task, false));
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(task.success());
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<Value> expected(Value::CreateStringValue(example_url1_));
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  profile_->GetPrefs()->Set(prefs::kHomePage, *expected);
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<const Value> actual(GetSyncedValue(prefs::kHomePage));
357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(actual.get());
358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(expected->Equals(actual.get()));
359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ProfileSyncServicePreferenceTest, UpdatedSyncNodeActionUpdate) {
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  profile_->GetPrefs()->SetString(prefs::kHomePage, example_url0_);
363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreateRootTask task(this, syncable::PREFERENCES);
364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(StartSyncService(&task, false));
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(task.success());
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<Value> expected(Value::CreateStringValue(example_url1_));
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_NE(SetSyncedValue(prefs::kHomePage, *expected), sync_api::kInvalidId);
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int64 node_id = model_associator_->GetSyncIdFromChromeId(prefs::kHomePage);
370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<SyncManager::ChangeRecord> record(new SyncManager::ChangeRecord);
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  record->action = SyncManager::ChangeRecord::ACTION_UPDATE;
372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  record->id = node_id;
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
37472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    sync_api::WriteTransaction trans(service_->GetUserShare());
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    change_processor_->ApplyChangesFromSyncModel(&trans, record.get(), 1);
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const Value& actual = GetPreferenceValue(prefs::kHomePage);
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(expected->Equals(&actual));
380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
382c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ProfileSyncServicePreferenceTest, UpdatedSyncNodeActionAdd) {
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreateRootTask task(this, syncable::PREFERENCES);
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(StartSyncService(&task, false));
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(task.success());
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<Value> expected(Value::CreateStringValue(example_url0_));
388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int64 node_id = SetSyncedValue(prefs::kHomePage, *expected);
389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_NE(node_id, sync_api::kInvalidId);
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<SyncManager::ChangeRecord> record(new SyncManager::ChangeRecord);
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  record->action = SyncManager::ChangeRecord::ACTION_ADD;
392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  record->id = node_id;
393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
39472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    sync_api::WriteTransaction trans(service_->GetUserShare());
395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    change_processor_->ApplyChangesFromSyncModel(&trans, record.get(), 1);
396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const Value& actual = GetPreferenceValue(prefs::kHomePage);
399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(expected->Equals(&actual));
400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(node_id,
401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            model_associator_->GetSyncIdFromChromeId(prefs::kHomePage));
402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ProfileSyncServicePreferenceTest, UpdatedSyncNodeUnknownPreference) {
405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreateRootTask task(this, syncable::PREFERENCES);
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(StartSyncService(&task, false));
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(task.success());
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<Value> expected(Value::CreateStringValue(example_url0_));
4103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int64 node_id = SetSyncedValue("unknown preference", *expected);
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_NE(node_id, sync_api::kInvalidId);
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<SyncManager::ChangeRecord> record(new SyncManager::ChangeRecord);
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  record->action = SyncManager::ChangeRecord::ACTION_ADD;
414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  record->id = node_id;
415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
41672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    sync_api::WriteTransaction trans(service_->GetUserShare());
417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    change_processor_->ApplyChangesFromSyncModel(&trans, record.get(), 1);
418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Nothing interesting happens on the client when it gets an update
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // of an unknown preference.  We just should not crash.
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
424c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ProfileSyncServicePreferenceTest, ManagedPreferences) {
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Make the homepage preference managed.
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<Value> managed_value(
4273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      Value::CreateStringValue("http://example.com"));
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  prefs_->SetManagedPref(prefs::kHomePage, managed_value->DeepCopy());
429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreateRootTask task(this, syncable::PREFERENCES);
431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(StartSyncService(&task, false));
432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(task.success());
433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Changing the homepage preference should not sync anything.
435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<Value> user_value(
4363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      Value::CreateStringValue("http://chromium..com"));
437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  prefs_->SetUserPref(prefs::kHomePage, user_value->DeepCopy());
438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(NULL, GetSyncedValue(prefs::kHomePage));
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // An incoming sync transaction shouldn't change the user value.
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<Value> sync_value(
4423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      Value::CreateStringValue("http://crbug.com"));
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int64 node_id = SetSyncedValue(prefs::kHomePage, *sync_value);
444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_NE(node_id, sync_api::kInvalidId);
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<SyncManager::ChangeRecord> record(new SyncManager::ChangeRecord);
446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  record->action = SyncManager::ChangeRecord::ACTION_UPDATE;
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  record->id = node_id;
448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
44972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    sync_api::WriteTransaction trans(service_->GetUserShare());
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    change_processor_->ApplyChangesFromSyncModel(&trans, record.get(), 1);
451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
4523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(managed_value->Equals(
4533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      prefs_->GetManagedPref(prefs::kHomePage)));
4543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(user_value->Equals(
4553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      prefs_->GetUserPref(prefs::kHomePage)));
4563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
4573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4583345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(ProfileSyncServicePreferenceTest, DynamicManagedPreferences) {
4593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CreateRootTask task(this, syncable::PREFERENCES);
4603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_TRUE(StartSyncService(&task, false));
4613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_TRUE(task.success());
4623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<Value> initial_value(
4643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      Value::CreateStringValue("http://example.com/initial"));
4653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  profile_->GetPrefs()->Set(prefs::kHomePage, *initial_value);
4663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<const Value> actual(GetSyncedValue(prefs::kHomePage));
4673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(initial_value->Equals(actual.get()));
4683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Switch kHomePage to managed and set a different value.
4703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<Value> managed_value(
4713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      Value::CreateStringValue("http://example.com/managed"));
4723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  profile_->GetTestingPrefService()->SetManagedPref(
4733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      prefs::kHomePage, managed_value->DeepCopy());
4743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Sync node should be gone.
4763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(sync_api::kInvalidId,
4773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            model_associator_->GetSyncIdFromChromeId(prefs::kHomePage));
4783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Change the sync value.
4803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<Value> sync_value(
4813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      Value::CreateStringValue("http://example.com/sync"));
4823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int64 node_id = SetSyncedValue(prefs::kHomePage, *sync_value);
4833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_NE(node_id, sync_api::kInvalidId);
4843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<SyncManager::ChangeRecord> record(new SyncManager::ChangeRecord);
4853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  record->action = SyncManager::ChangeRecord::ACTION_ADD;
4863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  record->id = node_id;
4873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  {
48872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    sync_api::WriteTransaction trans(service_->GetUserShare());
4893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    change_processor_->ApplyChangesFromSyncModel(&trans, record.get(), 1);
4903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
4913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // The pref value should still be the one dictated by policy.
4933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(managed_value->Equals(&GetPreferenceValue(prefs::kHomePage)));
4943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Switch kHomePage back to unmanaged.
4963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  profile_->GetTestingPrefService()->RemoveManagedPref(prefs::kHomePage);
4973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Sync value should be picked up.
4993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(sync_value->Equals(&GetPreferenceValue(prefs::kHomePage)));
500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
501