Popular sites on the NTP: check that experiment group StartsWith (rather than IS...
[chromium-blink-merge.git] / chrome / browser / supervised_user / supervised_user_settings_service_unittest.cc
blob3e82a5d7c5b58f8e43fc6d5dc3affe78be3da199
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "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/supervised_user/supervised_user_settings_service.h"
11 #include "content/public/test/test_browser_thread_bundle.h"
12 #include "sync/api/fake_sync_change_processor.h"
13 #include "sync/api/sync_change.h"
14 #include "sync/api/sync_change_processor_wrapper_for_test.h"
15 #include "sync/api/sync_error_factory_mock.h"
16 #include "sync/protocol/sync.pb.h"
17 #include "testing/gtest/include/gtest/gtest.h"
19 namespace {
21 class MockSyncErrorFactory : public syncer::SyncErrorFactory {
22 public:
23 explicit MockSyncErrorFactory(syncer::ModelType type);
24 ~MockSyncErrorFactory() override;
26 // SyncErrorFactory implementation:
27 syncer::SyncError CreateAndUploadError(
28 const tracked_objects::Location& location,
29 const std::string& message) override;
31 private:
32 syncer::ModelType type_;
34 DISALLOW_COPY_AND_ASSIGN(MockSyncErrorFactory);
37 MockSyncErrorFactory::MockSyncErrorFactory(syncer::ModelType type)
38 : type_(type) {}
40 MockSyncErrorFactory::~MockSyncErrorFactory() {}
42 syncer::SyncError MockSyncErrorFactory::CreateAndUploadError(
43 const tracked_objects::Location& location,
44 const std::string& message) {
45 return syncer::SyncError(location,
46 syncer::SyncError::DATATYPE_ERROR,
47 message,
48 type_);
51 } // namespace
53 const char kAtomicItemName[] = "X-Wombat";
54 const char kSettingsName[] = "TestingSetting";
55 const char kSettingsValue[] = "SettingsValue";
56 const char kSplitItemName[] = "X-SuperMoosePowers";
58 class SupervisedUserSettingsServiceTest : public ::testing::Test {
59 protected:
60 SupervisedUserSettingsServiceTest() : settings_service_(nullptr) {}
61 ~SupervisedUserSettingsServiceTest() override {}
63 scoped_ptr<syncer::SyncChangeProcessor> CreateSyncProcessor() {
64 sync_processor_.reset(new syncer::FakeSyncChangeProcessor);
65 return scoped_ptr<syncer::SyncChangeProcessor>(
66 new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get()));
69 void StartSyncing(const syncer::SyncDataList& initial_sync_data) {
70 scoped_ptr<syncer::SyncErrorFactory> error_handler(
71 new MockSyncErrorFactory(syncer::SUPERVISED_USER_SETTINGS));
72 syncer::SyncMergeResult result = settings_service_.MergeDataAndStartSyncing(
73 syncer::SUPERVISED_USER_SETTINGS,
74 initial_sync_data,
75 CreateSyncProcessor(),
76 error_handler.Pass());
77 EXPECT_FALSE(result.error().IsSet());
80 void UploadSplitItem(const std::string& key, const std::string& value) {
81 split_items_.SetStringWithoutPathExpansion(key, value);
82 settings_service_.UploadItem(
83 SupervisedUserSettingsService::MakeSplitSettingKey(kSplitItemName,
84 key),
85 scoped_ptr<base::Value>(new base::StringValue(value)));
88 void UploadAtomicItem(const std::string& value) {
89 atomic_setting_value_.reset(new base::StringValue(value));
90 settings_service_.UploadItem(
91 kAtomicItemName,
92 scoped_ptr<base::Value>(new base::StringValue(value)));
95 void VerifySyncDataItem(syncer::SyncData sync_data) {
96 const sync_pb::ManagedUserSettingSpecifics& supervised_user_setting =
97 sync_data.GetSpecifics().managed_user_setting();
98 base::Value* expected_value = NULL;
99 if (supervised_user_setting.name() == kAtomicItemName) {
100 expected_value = atomic_setting_value_.get();
101 } else {
102 EXPECT_TRUE(base::StartsWith(supervised_user_setting.name(),
103 std::string(kSplitItemName) + ':',
104 base::CompareCase::SENSITIVE));
105 std::string key =
106 supervised_user_setting.name().substr(strlen(kSplitItemName) + 1);
107 EXPECT_TRUE(split_items_.GetWithoutPathExpansion(key, &expected_value));
110 scoped_ptr<base::Value> value(
111 base::JSONReader::DeprecatedRead(supervised_user_setting.value()));
112 EXPECT_TRUE(expected_value->Equals(value.get()));
115 void OnNewSettingsAvailable(const base::DictionaryValue* settings) {
116 if (!settings)
117 settings_.reset();
118 else
119 settings_.reset(settings->DeepCopy());
122 // testing::Test overrides:
123 void SetUp() override {
124 TestingPrefStore* pref_store = new TestingPrefStore;
125 settings_service_.Init(pref_store);
126 user_settings_subscription_ = settings_service_.Subscribe(
127 base::Bind(&SupervisedUserSettingsServiceTest::OnNewSettingsAvailable,
128 base::Unretained(this)));
129 pref_store->SetInitializationCompleted();
130 ASSERT_FALSE(settings_);
131 settings_service_.SetActive(true);
132 ASSERT_TRUE(settings_);
135 void TearDown() override { settings_service_.Shutdown(); }
137 content::TestBrowserThreadBundle thread_bundle_;
138 base::DictionaryValue split_items_;
139 scoped_ptr<base::Value> atomic_setting_value_;
140 SupervisedUserSettingsService settings_service_;
141 scoped_ptr<base::DictionaryValue> settings_;
142 scoped_ptr<base::CallbackList<void(
143 const base::DictionaryValue*)>::Subscription> user_settings_subscription_;
145 scoped_ptr<syncer::FakeSyncChangeProcessor> sync_processor_;
148 TEST_F(SupervisedUserSettingsServiceTest, ProcessAtomicSetting) {
149 StartSyncing(syncer::SyncDataList());
150 ASSERT_TRUE(settings_);
151 const base::Value* value = NULL;
152 EXPECT_FALSE(settings_->GetWithoutPathExpansion(kSettingsName, &value));
154 settings_.reset();
155 syncer::SyncData data =
156 SupervisedUserSettingsService::CreateSyncDataForSetting(
157 kSettingsName, base::StringValue(kSettingsValue));
158 syncer::SyncChangeList change_list;
159 change_list.push_back(
160 syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_ADD, data));
161 syncer::SyncError error =
162 settings_service_.ProcessSyncChanges(FROM_HERE, change_list);
163 EXPECT_FALSE(error.IsSet()) << error.ToString();
164 ASSERT_TRUE(settings_);
165 ASSERT_TRUE(settings_->GetWithoutPathExpansion(kSettingsName, &value));
166 std::string string_value;
167 EXPECT_TRUE(value->GetAsString(&string_value));
168 EXPECT_EQ(kSettingsValue, string_value);
171 TEST_F(SupervisedUserSettingsServiceTest, ProcessSplitSetting) {
172 StartSyncing(syncer::SyncDataList());
173 ASSERT_TRUE(settings_);
174 const base::Value* value = NULL;
175 EXPECT_FALSE(settings_->GetWithoutPathExpansion(kSettingsName, &value));
177 base::DictionaryValue dict;
178 dict.SetString("foo", "bar");
179 dict.SetBoolean("awesomesauce", true);
180 dict.SetInteger("eaudecologne", 4711);
182 settings_.reset();
183 syncer::SyncChangeList change_list;
184 for (base::DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) {
185 syncer::SyncData data =
186 SupervisedUserSettingsService::CreateSyncDataForSetting(
187 SupervisedUserSettingsService::MakeSplitSettingKey(kSettingsName,
188 it.key()),
189 it.value());
190 change_list.push_back(
191 syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_ADD, data));
193 syncer::SyncError error =
194 settings_service_.ProcessSyncChanges(FROM_HERE, change_list);
195 EXPECT_FALSE(error.IsSet()) << error.ToString();
196 ASSERT_TRUE(settings_);
197 ASSERT_TRUE(settings_->GetWithoutPathExpansion(kSettingsName, &value));
198 const base::DictionaryValue* dict_value = NULL;
199 ASSERT_TRUE(value->GetAsDictionary(&dict_value));
200 EXPECT_TRUE(dict_value->Equals(&dict));
203 TEST_F(SupervisedUserSettingsServiceTest, SetLocalSetting) {
204 const base::Value* value = NULL;
205 EXPECT_FALSE(settings_->GetWithoutPathExpansion(kSettingsName, &value));
207 settings_.reset();
208 settings_service_.SetLocalSetting(
209 kSettingsName,
210 scoped_ptr<base::Value>(new base::StringValue(kSettingsValue)));
211 ASSERT_TRUE(settings_);
212 ASSERT_TRUE(settings_->GetWithoutPathExpansion(kSettingsName, &value));
213 std::string string_value;
214 EXPECT_TRUE(value->GetAsString(&string_value));
215 EXPECT_EQ(kSettingsValue, string_value);
218 TEST_F(SupervisedUserSettingsServiceTest, UploadItem) {
219 UploadSplitItem("foo", "bar");
220 UploadSplitItem("blurp", "baz");
221 UploadAtomicItem("hurdle");
223 // Uploading should produce changes when we start syncing.
224 StartSyncing(syncer::SyncDataList());
225 ASSERT_EQ(3u, sync_processor_->changes().size());
226 for (const syncer::SyncChange& sync_change : sync_processor_->changes()) {
227 ASSERT_TRUE(sync_change.IsValid());
228 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, sync_change.change_type());
229 VerifySyncDataItem(sync_change.sync_data());
232 // It should also show up in local Sync data.
233 syncer::SyncDataList sync_data =
234 settings_service_.GetAllSyncData(syncer::SUPERVISED_USER_SETTINGS);
235 EXPECT_EQ(3u, sync_data.size());
236 for (const syncer::SyncData& sync_data_item : sync_data)
237 VerifySyncDataItem(sync_data_item);
239 // Uploading after we have started syncing should work too.
240 sync_processor_->changes().clear();
241 UploadSplitItem("froodle", "narf");
242 ASSERT_EQ(1u, sync_processor_->changes().size());
243 syncer::SyncChange change = sync_processor_->changes()[0];
244 ASSERT_TRUE(change.IsValid());
245 EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
246 VerifySyncDataItem(change.sync_data());
248 sync_data = settings_service_.GetAllSyncData(
249 syncer::SUPERVISED_USER_SETTINGS);
250 EXPECT_EQ(4u, sync_data.size());
251 for (const syncer::SyncData& sync_data_item : sync_data)
252 VerifySyncDataItem(sync_data_item);
254 // Uploading an item with a previously seen key should create an UPDATE
255 // action.
256 sync_processor_->changes().clear();
257 UploadSplitItem("blurp", "snarl");
258 ASSERT_EQ(1u, sync_processor_->changes().size());
259 change = sync_processor_->changes()[0];
260 ASSERT_TRUE(change.IsValid());
261 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
262 VerifySyncDataItem(change.sync_data());
264 sync_data = settings_service_.GetAllSyncData(
265 syncer::SUPERVISED_USER_SETTINGS);
266 EXPECT_EQ(4u, sync_data.size());
267 for (const syncer::SyncData& sync_data_item : sync_data)
268 VerifySyncDataItem(sync_data_item);
270 sync_processor_->changes().clear();
271 UploadAtomicItem("fjord");
272 ASSERT_EQ(1u, sync_processor_->changes().size());
273 change = sync_processor_->changes()[0];
274 ASSERT_TRUE(change.IsValid());
275 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
276 VerifySyncDataItem(change.sync_data());
278 sync_data = settings_service_.GetAllSyncData(
279 syncer::SUPERVISED_USER_SETTINGS);
280 EXPECT_EQ(4u, sync_data.size());
281 for (const syncer::SyncData& sync_data_item : sync_data)
282 VerifySyncDataItem(sync_data_item);
284 // The uploaded items should not show up as settings.
285 const base::Value* value = NULL;
286 EXPECT_FALSE(settings_->GetWithoutPathExpansion(kAtomicItemName, &value));
287 EXPECT_FALSE(settings_->GetWithoutPathExpansion(kSplitItemName, &value));
289 // Restarting sync should not create any new changes.
290 settings_service_.StopSyncing(syncer::SUPERVISED_USER_SETTINGS);
291 StartSyncing(sync_data);
292 ASSERT_EQ(0u, sync_processor_->changes().size());