blob: 619daca538eef3d38fd6796fce6c8e5db6a904da [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <string>
#include "base/bind.h"
#include "base/json/json_writer.h"
#include "base/prefs/pref_service.h"
#include "chrome/browser/supervised_user/supervised_user_shared_settings_service.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/testing_profile.h"
#include "sync/api/fake_sync_change_processor.h"
#include "sync/api/sync_change.h"
#include "sync/api/sync_change_processor_wrapper_for_test.h"
#include "sync/api/sync_error_factory_mock.h"
#include "sync/protocol/sync.pb.h"
#include "testing/gtest/include/gtest/gtest.h"
using base::DictionaryValue;
using base::FundamentalValue;
using base::StringValue;
using base::Value;
using sync_pb::ManagedUserSharedSettingSpecifics;
using syncer::SUPERVISED_USER_SHARED_SETTINGS;
using syncer::SyncChange;
using syncer::SyncChangeList;
using syncer::SyncChangeProcessor;
using syncer::SyncChangeProcessorWrapperForTest;
using syncer::SyncData;
using syncer::SyncDataList;
using syncer::SyncError;
using syncer::SyncErrorFactory;
using syncer::SyncMergeResult;
namespace {
class MockSyncErrorFactory : public syncer::SyncErrorFactory {
public:
explicit MockSyncErrorFactory(syncer::ModelType type);
~MockSyncErrorFactory() override;
// SyncErrorFactory implementation:
syncer::SyncError CreateAndUploadError(
const tracked_objects::Location& location,
const std::string& message) override;
private:
syncer::ModelType type_;
DISALLOW_COPY_AND_ASSIGN(MockSyncErrorFactory);
};
MockSyncErrorFactory::MockSyncErrorFactory(syncer::ModelType type)
: type_(type) {}
MockSyncErrorFactory::~MockSyncErrorFactory() {}
syncer::SyncError MockSyncErrorFactory::CreateAndUploadError(
const tracked_objects::Location& location,
const std::string& message) {
return syncer::SyncError(location, SyncError::DATATYPE_ERROR, message, type_);
}
// Convenience method to allow us to use EXPECT_EQ to compare values.
std::string ToJson(const Value* value) {
if (!value)
return std::string();
std::string json_value;
base::JSONWriter::Write(value, &json_value);
return json_value;
}
} // namespace
class SupervisedUserSharedSettingsServiceTest : public ::testing::Test {
protected:
typedef base::CallbackList<void(const std::string&, const std::string&)>
CallbackList;
SupervisedUserSharedSettingsServiceTest()
: settings_service_(profile_.GetPrefs()) {}
~SupervisedUserSharedSettingsServiceTest() override {}
void StartSyncing(const syncer::SyncDataList& initial_sync_data) {
sync_processor_.reset(new syncer::FakeSyncChangeProcessor);
scoped_ptr<syncer::SyncErrorFactory> error_handler(
new MockSyncErrorFactory(SUPERVISED_USER_SHARED_SETTINGS));
SyncMergeResult result = settings_service_.MergeDataAndStartSyncing(
SUPERVISED_USER_SHARED_SETTINGS,
initial_sync_data,
scoped_ptr<SyncChangeProcessor>(
new SyncChangeProcessorWrapperForTest(sync_processor_.get())),
error_handler.Pass());
EXPECT_FALSE(result.error().IsSet());
}
const base::DictionaryValue* GetAllSettings() {
return profile_.GetPrefs()->GetDictionary(
prefs::kSupervisedUserSharedSettings);
}
void VerifySyncChangesAndClear() {
SyncChangeList& changes = sync_processor_->changes();
for (const SyncChange& sync_change : changes) {
const sync_pb::ManagedUserSharedSettingSpecifics& setting =
sync_change.sync_data().GetSpecifics().managed_user_shared_setting();
EXPECT_EQ(
setting.value(),
ToJson(settings_service_.GetValue(setting.mu_id(), setting.key())));
}
changes.clear();
}
// testing::Test overrides:
void SetUp() override {
subscription_ = settings_service_.Subscribe(
base::Bind(&SupervisedUserSharedSettingsServiceTest::OnSettingChanged,
base::Unretained(this)));
}
void TearDown() override { settings_service_.Shutdown(); }
void OnSettingChanged(const std::string& su_id, const std::string& key) {
const Value* value = settings_service_.GetValue(su_id, key);
ASSERT_TRUE(value);
changed_settings_.push_back(
SupervisedUserSharedSettingsService::CreateSyncDataForSetting(
su_id, key, *value, true));
}
TestingProfile profile_;
SupervisedUserSharedSettingsService settings_service_;
SyncDataList changed_settings_;
scoped_ptr<CallbackList::Subscription> subscription_;
scoped_ptr<syncer::FakeSyncChangeProcessor> sync_processor_;
};
TEST_F(SupervisedUserSharedSettingsServiceTest, Empty) {
StartSyncing(SyncDataList());
EXPECT_EQ(0u, sync_processor_->changes().size());
EXPECT_EQ(0u, changed_settings_.size());
EXPECT_EQ(
0u,
settings_service_.GetAllSyncData(SUPERVISED_USER_SHARED_SETTINGS).size());
EXPECT_EQ(0u, GetAllSettings()->size());
}
TEST_F(SupervisedUserSharedSettingsServiceTest, SetAndGet) {
StartSyncing(SyncDataList());
const char kIdA[] = "aaaaaa";
const char kIdB[] = "bbbbbb";
const char kIdC[] = "cccccc";
StringValue name("Jack");
FundamentalValue age(8);
StringValue bar("bar");
settings_service_.SetValue(kIdA, "name", name);
ASSERT_EQ(1u, sync_processor_->changes().size());
VerifySyncChangesAndClear();
settings_service_.SetValue(kIdA, "age", FundamentalValue(6));
ASSERT_EQ(1u, sync_processor_->changes().size());
VerifySyncChangesAndClear();
settings_service_.SetValue(kIdA, "age", age);
ASSERT_EQ(1u, sync_processor_->changes().size());
VerifySyncChangesAndClear();
settings_service_.SetValue(kIdB, "foo", bar);
ASSERT_EQ(1u, sync_processor_->changes().size());
VerifySyncChangesAndClear();
EXPECT_EQ(
3u,
settings_service_.GetAllSyncData(SUPERVISED_USER_SHARED_SETTINGS).size());
EXPECT_EQ(ToJson(&name), ToJson(settings_service_.GetValue(kIdA, "name")));
EXPECT_EQ(ToJson(&age), ToJson(settings_service_.GetValue(kIdA, "age")));
EXPECT_EQ(ToJson(&bar), ToJson(settings_service_.GetValue(kIdB, "foo")));
EXPECT_FALSE(settings_service_.GetValue(kIdA, "foo"));
EXPECT_FALSE(settings_service_.GetValue(kIdB, "name"));
EXPECT_FALSE(settings_service_.GetValue(kIdC, "name"));
}
TEST_F(SupervisedUserSharedSettingsServiceTest, Merge) {
// Set initial values, then stop syncing so we can restart.
StartSyncing(SyncDataList());
const char kIdA[] = "aaaaaa";
const char kIdB[] = "bbbbbb";
const char kIdC[] = "cccccc";
FundamentalValue age(8);
StringValue bar("bar");
settings_service_.SetValue(kIdA, "name", StringValue("Jack"));
settings_service_.SetValue(kIdA, "age", age);
settings_service_.SetValue(kIdB, "foo", bar);
settings_service_.StopSyncing(SUPERVISED_USER_SHARED_SETTINGS);
StringValue name("Jill");
StringValue blurp("blurp");
SyncDataList sync_data;
sync_data.push_back(
SupervisedUserSharedSettingsService::CreateSyncDataForSetting(
kIdA, "name", name, true));
sync_data.push_back(
SupervisedUserSharedSettingsService::CreateSyncDataForSetting(
kIdC, "baz", blurp, true));
StartSyncing(sync_data);
EXPECT_EQ(2u, sync_processor_->changes().size());
VerifySyncChangesAndClear();
EXPECT_EQ(2u, changed_settings_.size());
EXPECT_EQ(
4u,
settings_service_.GetAllSyncData(SUPERVISED_USER_SHARED_SETTINGS).size());
EXPECT_EQ(ToJson(&name),
ToJson(settings_service_.GetValue(kIdA, "name")));
EXPECT_EQ(ToJson(&age), ToJson(settings_service_.GetValue(kIdA, "age")));
EXPECT_EQ(ToJson(&bar), ToJson(settings_service_.GetValue(kIdB, "foo")));
EXPECT_EQ(ToJson(&blurp), ToJson(settings_service_.GetValue(kIdC, "baz")));
EXPECT_FALSE(settings_service_.GetValue(kIdA, "foo"));
EXPECT_FALSE(settings_service_.GetValue(kIdB, "name"));
EXPECT_FALSE(settings_service_.GetValue(kIdC, "name"));
}
TEST_F(SupervisedUserSharedSettingsServiceTest, ProcessChanges) {
StartSyncing(SyncDataList());
const char kIdA[] = "aaaaaa";
const char kIdB[] = "bbbbbb";
const char kIdC[] = "cccccc";
FundamentalValue age(8);
StringValue bar("bar");
settings_service_.SetValue(kIdA, "name", StringValue("Jack"));
settings_service_.SetValue(kIdA, "age", age);
settings_service_.SetValue(kIdB, "foo", bar);
StringValue name("Jill");
StringValue blurp("blurp");
SyncChangeList changes;
changes.push_back(
SyncChange(FROM_HERE,
SyncChange::ACTION_UPDATE,
SupervisedUserSharedSettingsService::CreateSyncDataForSetting(
kIdA, "name", name, true)));
changes.push_back(
SyncChange(FROM_HERE,
SyncChange::ACTION_ADD,
SupervisedUserSharedSettingsService::CreateSyncDataForSetting(
kIdC, "baz", blurp, true)));
SyncError error = settings_service_.ProcessSyncChanges(FROM_HERE, changes);
EXPECT_FALSE(error.IsSet()) << error.ToString();
EXPECT_EQ(2u, changed_settings_.size());
EXPECT_EQ(
4u,
settings_service_.GetAllSyncData(SUPERVISED_USER_SHARED_SETTINGS).size());
EXPECT_EQ(ToJson(&name),
ToJson(settings_service_.GetValue(kIdA, "name")));
EXPECT_EQ(ToJson(&age), ToJson(settings_service_.GetValue(kIdA, "age")));
EXPECT_EQ(ToJson(&bar), ToJson(settings_service_.GetValue(kIdB, "foo")));
EXPECT_EQ(ToJson(&blurp), ToJson(settings_service_.GetValue(kIdC, "baz")));
EXPECT_FALSE(settings_service_.GetValue(kIdA, "foo"));
EXPECT_FALSE(settings_service_.GetValue(kIdB, "name"));
EXPECT_FALSE(settings_service_.GetValue(kIdC, "name"));
}