OLD | NEW |
| (Empty) |
1 // Copyright 2013 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 "base/bind.h" | |
6 #include "base/callback.h" | |
7 #include "base/json/json_reader.h" | |
8 #include "base/prefs/testing_pref_store.h" | |
9 #include "base/strings/string_util.h" | |
10 #include "chrome/browser/managed_mode/managed_user_settings_service.h" | |
11 #include "sync/api/fake_sync_change_processor.h" | |
12 #include "sync/api/sync_change.h" | |
13 #include "sync/api/sync_change_processor_wrapper_for_test.h" | |
14 #include "sync/api/sync_error_factory_mock.h" | |
15 #include "sync/protocol/sync.pb.h" | |
16 #include "testing/gtest/include/gtest/gtest.h" | |
17 | |
18 namespace { | |
19 | |
20 class MockSyncErrorFactory : public syncer::SyncErrorFactory { | |
21 public: | |
22 explicit MockSyncErrorFactory(syncer::ModelType type); | |
23 virtual ~MockSyncErrorFactory(); | |
24 | |
25 // SyncErrorFactory implementation: | |
26 virtual syncer::SyncError CreateAndUploadError( | |
27 const tracked_objects::Location& location, | |
28 const std::string& message) OVERRIDE; | |
29 | |
30 private: | |
31 syncer::ModelType type_; | |
32 | |
33 DISALLOW_COPY_AND_ASSIGN(MockSyncErrorFactory); | |
34 }; | |
35 | |
36 MockSyncErrorFactory::MockSyncErrorFactory(syncer::ModelType type) | |
37 : type_(type) {} | |
38 | |
39 MockSyncErrorFactory::~MockSyncErrorFactory() {} | |
40 | |
41 syncer::SyncError MockSyncErrorFactory::CreateAndUploadError( | |
42 const tracked_objects::Location& location, | |
43 const std::string& message) { | |
44 return syncer::SyncError(location, | |
45 syncer::SyncError::DATATYPE_ERROR, | |
46 message, | |
47 type_); | |
48 } | |
49 | |
50 } // namespace | |
51 | |
52 const char kAtomicItemName[] = "X-Wombat"; | |
53 const char kSettingsName[] = "TestingSetting"; | |
54 const char kSettingsValue[] = "SettingsValue"; | |
55 const char kSplitItemName[] = "X-SuperMoosePowers"; | |
56 | |
57 class ManagedUserSettingsServiceTest : public ::testing::Test { | |
58 protected: | |
59 ManagedUserSettingsServiceTest() {} | |
60 virtual ~ManagedUserSettingsServiceTest() {} | |
61 | |
62 scoped_ptr<syncer::SyncChangeProcessor> CreateSyncProcessor() { | |
63 sync_processor_.reset(new syncer::FakeSyncChangeProcessor); | |
64 return scoped_ptr<syncer::SyncChangeProcessor>( | |
65 new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get())); | |
66 } | |
67 | |
68 void StartSyncing(const syncer::SyncDataList& initial_sync_data) { | |
69 scoped_ptr<syncer::SyncErrorFactory> error_handler( | |
70 new MockSyncErrorFactory(syncer::SUPERVISED_USER_SETTINGS)); | |
71 syncer::SyncMergeResult result = settings_service_.MergeDataAndStartSyncing( | |
72 syncer::SUPERVISED_USER_SETTINGS, | |
73 initial_sync_data, | |
74 CreateSyncProcessor(), | |
75 error_handler.Pass()); | |
76 EXPECT_FALSE(result.error().IsSet()); | |
77 } | |
78 | |
79 void UploadSplitItem(const std::string& key, const std::string& value) { | |
80 split_items_.SetStringWithoutPathExpansion(key, value); | |
81 settings_service_.UploadItem( | |
82 ManagedUserSettingsService::MakeSplitSettingKey(kSplitItemName, | |
83 key), | |
84 scoped_ptr<base::Value>(new base::StringValue(value))); | |
85 } | |
86 | |
87 void UploadAtomicItem(const std::string& value) { | |
88 atomic_setting_value_.reset(new base::StringValue(value)); | |
89 settings_service_.UploadItem( | |
90 kAtomicItemName, | |
91 scoped_ptr<base::Value>(new base::StringValue(value))); | |
92 } | |
93 | |
94 void VerifySyncDataItem(syncer::SyncData sync_data) { | |
95 const sync_pb::ManagedUserSettingSpecifics& managed_user_setting = | |
96 sync_data.GetSpecifics().managed_user_setting(); | |
97 base::Value* expected_value = NULL; | |
98 if (managed_user_setting.name() == kAtomicItemName) { | |
99 expected_value = atomic_setting_value_.get(); | |
100 } else { | |
101 EXPECT_TRUE(StartsWithASCII(managed_user_setting.name(), | |
102 std::string(kSplitItemName) + ':', | |
103 true)); | |
104 std::string key = | |
105 managed_user_setting.name().substr(strlen(kSplitItemName) + 1); | |
106 EXPECT_TRUE(split_items_.GetWithoutPathExpansion(key, &expected_value)); | |
107 } | |
108 | |
109 scoped_ptr<base::Value> value( | |
110 base::JSONReader::Read(managed_user_setting.value())); | |
111 EXPECT_TRUE(expected_value->Equals(value.get())); | |
112 } | |
113 | |
114 void OnNewSettingsAvailable(const base::DictionaryValue* settings) { | |
115 if (!settings) | |
116 settings_.reset(); | |
117 else | |
118 settings_.reset(settings->DeepCopy()); | |
119 } | |
120 | |
121 // testing::Test overrides: | |
122 virtual void SetUp() OVERRIDE { | |
123 TestingPrefStore* pref_store = new TestingPrefStore; | |
124 settings_service_.Init(pref_store); | |
125 settings_service_.Subscribe( | |
126 base::Bind(&ManagedUserSettingsServiceTest::OnNewSettingsAvailable, | |
127 base::Unretained(this))); | |
128 pref_store->SetInitializationCompleted(); | |
129 ASSERT_FALSE(settings_); | |
130 settings_service_.SetActive(true); | |
131 ASSERT_TRUE(settings_); | |
132 } | |
133 | |
134 virtual void TearDown() OVERRIDE { | |
135 settings_service_.Shutdown(); | |
136 } | |
137 | |
138 base::DictionaryValue split_items_; | |
139 scoped_ptr<base::Value> atomic_setting_value_; | |
140 ManagedUserSettingsService settings_service_; | |
141 scoped_ptr<base::DictionaryValue> settings_; | |
142 | |
143 scoped_ptr<syncer::FakeSyncChangeProcessor> sync_processor_; | |
144 }; | |
145 | |
146 TEST_F(ManagedUserSettingsServiceTest, ProcessAtomicSetting) { | |
147 StartSyncing(syncer::SyncDataList()); | |
148 ASSERT_TRUE(settings_); | |
149 const base::Value* value = NULL; | |
150 EXPECT_FALSE(settings_->GetWithoutPathExpansion(kSettingsName, &value)); | |
151 | |
152 settings_.reset(); | |
153 syncer::SyncData data = | |
154 ManagedUserSettingsService::CreateSyncDataForSetting( | |
155 kSettingsName, base::StringValue(kSettingsValue)); | |
156 syncer::SyncChangeList change_list; | |
157 change_list.push_back( | |
158 syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_ADD, data)); | |
159 syncer::SyncError error = | |
160 settings_service_.ProcessSyncChanges(FROM_HERE, change_list); | |
161 EXPECT_FALSE(error.IsSet()) << error.ToString(); | |
162 ASSERT_TRUE(settings_); | |
163 ASSERT_TRUE(settings_->GetWithoutPathExpansion(kSettingsName, &value)); | |
164 std::string string_value; | |
165 EXPECT_TRUE(value->GetAsString(&string_value)); | |
166 EXPECT_EQ(kSettingsValue, string_value); | |
167 } | |
168 | |
169 TEST_F(ManagedUserSettingsServiceTest, ProcessSplitSetting) { | |
170 StartSyncing(syncer::SyncDataList()); | |
171 ASSERT_TRUE(settings_); | |
172 const base::Value* value = NULL; | |
173 EXPECT_FALSE(settings_->GetWithoutPathExpansion(kSettingsName, &value)); | |
174 | |
175 base::DictionaryValue dict; | |
176 dict.SetString("foo", "bar"); | |
177 dict.SetBoolean("awesomesauce", true); | |
178 dict.SetInteger("eaudecologne", 4711); | |
179 | |
180 settings_.reset(); | |
181 syncer::SyncChangeList change_list; | |
182 for (base::DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) { | |
183 syncer::SyncData data = | |
184 ManagedUserSettingsService::CreateSyncDataForSetting( | |
185 ManagedUserSettingsService::MakeSplitSettingKey(kSettingsName, | |
186 it.key()), | |
187 it.value()); | |
188 change_list.push_back( | |
189 syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_ADD, data)); | |
190 } | |
191 syncer::SyncError error = | |
192 settings_service_.ProcessSyncChanges(FROM_HERE, change_list); | |
193 EXPECT_FALSE(error.IsSet()) << error.ToString(); | |
194 ASSERT_TRUE(settings_); | |
195 ASSERT_TRUE(settings_->GetWithoutPathExpansion(kSettingsName, &value)); | |
196 const base::DictionaryValue* dict_value = NULL; | |
197 ASSERT_TRUE(value->GetAsDictionary(&dict_value)); | |
198 EXPECT_TRUE(dict_value->Equals(&dict)); | |
199 } | |
200 | |
201 TEST_F(ManagedUserSettingsServiceTest, SetLocalSetting) { | |
202 const base::Value* value = NULL; | |
203 EXPECT_FALSE(settings_->GetWithoutPathExpansion(kSettingsName, &value)); | |
204 | |
205 settings_.reset(); | |
206 settings_service_.SetLocalSettingForTesting( | |
207 kSettingsName, | |
208 scoped_ptr<base::Value>(new base::StringValue(kSettingsValue))); | |
209 ASSERT_TRUE(settings_); | |
210 ASSERT_TRUE(settings_->GetWithoutPathExpansion(kSettingsName, &value)); | |
211 std::string string_value; | |
212 EXPECT_TRUE(value->GetAsString(&string_value)); | |
213 EXPECT_EQ(kSettingsValue, string_value); | |
214 } | |
215 | |
216 TEST_F(ManagedUserSettingsServiceTest, UploadItem) { | |
217 UploadSplitItem("foo", "bar"); | |
218 UploadSplitItem("blurp", "baz"); | |
219 UploadAtomicItem("hurdle"); | |
220 | |
221 // Uploading should produce changes when we start syncing. | |
222 StartSyncing(syncer::SyncDataList()); | |
223 ASSERT_EQ(3u, sync_processor_->changes().size()); | |
224 for (syncer::SyncChangeList::const_iterator it = | |
225 sync_processor_->changes().begin(); | |
226 it != sync_processor_->changes().end(); | |
227 ++it) { | |
228 ASSERT_TRUE(it->IsValid()); | |
229 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, it->change_type()); | |
230 VerifySyncDataItem(it->sync_data()); | |
231 } | |
232 | |
233 // It should also show up in local Sync data. | |
234 syncer::SyncDataList sync_data = | |
235 settings_service_.GetAllSyncData(syncer::SUPERVISED_USER_SETTINGS); | |
236 EXPECT_EQ(3u, sync_data.size()); | |
237 for (syncer::SyncDataList::const_iterator it = sync_data.begin(); | |
238 it != sync_data.end(); ++it) { | |
239 VerifySyncDataItem(*it); | |
240 } | |
241 | |
242 // Uploading after we have started syncing should work too. | |
243 sync_processor_->changes().clear(); | |
244 UploadSplitItem("froodle", "narf"); | |
245 ASSERT_EQ(1u, sync_processor_->changes().size()); | |
246 syncer::SyncChange change = sync_processor_->changes()[0]; | |
247 ASSERT_TRUE(change.IsValid()); | |
248 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type()); | |
249 VerifySyncDataItem(change.sync_data()); | |
250 | |
251 sync_data = settings_service_.GetAllSyncData( | |
252 syncer::SUPERVISED_USER_SETTINGS); | |
253 EXPECT_EQ(4u, sync_data.size()); | |
254 for (syncer::SyncDataList::const_iterator it = sync_data.begin(); | |
255 it != sync_data.end(); ++it) { | |
256 VerifySyncDataItem(*it); | |
257 } | |
258 | |
259 // Uploading an item with a previously seen key should create an UPDATE | |
260 // action. | |
261 sync_processor_->changes().clear(); | |
262 UploadSplitItem("blurp", "snarl"); | |
263 ASSERT_EQ(1u, sync_processor_->changes().size()); | |
264 change = sync_processor_->changes()[0]; | |
265 ASSERT_TRUE(change.IsValid()); | |
266 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type()); | |
267 VerifySyncDataItem(change.sync_data()); | |
268 | |
269 sync_data = settings_service_.GetAllSyncData( | |
270 syncer::SUPERVISED_USER_SETTINGS); | |
271 EXPECT_EQ(4u, sync_data.size()); | |
272 for (syncer::SyncDataList::const_iterator it = sync_data.begin(); | |
273 it != sync_data.end(); ++it) { | |
274 VerifySyncDataItem(*it); | |
275 } | |
276 | |
277 sync_processor_->changes().clear(); | |
278 UploadAtomicItem("fjord"); | |
279 ASSERT_EQ(1u, sync_processor_->changes().size()); | |
280 change = sync_processor_->changes()[0]; | |
281 ASSERT_TRUE(change.IsValid()); | |
282 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type()); | |
283 VerifySyncDataItem(change.sync_data()); | |
284 | |
285 sync_data = settings_service_.GetAllSyncData( | |
286 syncer::SUPERVISED_USER_SETTINGS); | |
287 EXPECT_EQ(4u, sync_data.size()); | |
288 for (syncer::SyncDataList::const_iterator it = sync_data.begin(); | |
289 it != sync_data.end(); ++it) { | |
290 VerifySyncDataItem(*it); | |
291 } | |
292 | |
293 // The uploaded items should not show up as settings. | |
294 const base::Value* value = NULL; | |
295 EXPECT_FALSE(settings_->GetWithoutPathExpansion(kAtomicItemName, &value)); | |
296 EXPECT_FALSE(settings_->GetWithoutPathExpansion(kSplitItemName, &value)); | |
297 | |
298 // Restarting sync should not create any new changes. | |
299 settings_service_.StopSyncing(syncer::SUPERVISED_USER_SETTINGS); | |
300 StartSyncing(sync_data); | |
301 ASSERT_EQ(0u, sync_processor_->changes().size()); | |
302 } | |
OLD | NEW |