158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// found in the LICENSE file.
458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/bind.h"
658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/callback.h"
758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/json/json_reader.h"
858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/prefs/testing_pref_store.h"
958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/strings/string_util.h"
1058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/managed_mode/managed_user_settings_service.h"
1158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "sync/api/sync_change.h"
1258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "sync/api/sync_error_factory_mock.h"
1358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "sync/protocol/sync.pb.h"
1458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
1558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace {
1758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class MockChangeProcessor : public syncer::SyncChangeProcessor {
1958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public:
2058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  MockChangeProcessor() {}
2158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual ~MockChangeProcessor() {}
2258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // SyncChangeProcessor implementation:
2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual syncer::SyncError ProcessSyncChanges(
2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      const tracked_objects::Location& from_here,
2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      const syncer::SyncChangeList& change_list) OVERRIDE;
2758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const
2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      OVERRIDE;
2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const syncer::SyncChangeList& changes() const { return change_list_; }
3158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) private:
3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  syncer::SyncChangeList change_list_;
3458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MockChangeProcessor);
3658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)syncer::SyncError MockChangeProcessor::ProcessSyncChanges(
3958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const tracked_objects::Location& from_here,
4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const syncer::SyncChangeList& change_list) {
4158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  change_list_ = change_list;
4258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return syncer::SyncError();
4358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)syncer::SyncDataList MockChangeProcessor::GetAllSyncData(
4658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    syncer::ModelType type) const {
4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return syncer::SyncDataList();
4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class MockSyncErrorFactory : public syncer::SyncErrorFactory {
5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public:
5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  explicit MockSyncErrorFactory(syncer::ModelType type);
5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual ~MockSyncErrorFactory();
5458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // SyncErrorFactory implementation:
5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual syncer::SyncError CreateAndUploadError(
5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      const tracked_objects::Location& location,
5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      const std::string& message) OVERRIDE;
5958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) private:
6158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  syncer::ModelType type_;
6258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MockSyncErrorFactory);
6458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
6558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)MockSyncErrorFactory::MockSyncErrorFactory(syncer::ModelType type)
6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    : type_(type) {}
6858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)MockSyncErrorFactory::~MockSyncErrorFactory() {}
7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)syncer::SyncError MockSyncErrorFactory::CreateAndUploadError(
7258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const tracked_objects::Location& location,
7358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const std::string& message) {
7458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return syncer::SyncError(location,
7558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                           syncer::SyncError::DATATYPE_ERROR,
7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                           message,
7758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                           type_);
7858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
8058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}  // namespace
8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kAtomicItemName[] = "X-Wombat";
8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kSettingsName[] = "TestingSetting";
8458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kSettingsValue[] = "SettingsValue";
8558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char kSplitItemName[] = "X-SuperMoosePowers";
8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class ManagedUserSettingsServiceTest : public ::testing::Test {
8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) protected:
8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ManagedUserSettingsServiceTest() {}
9058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual ~ManagedUserSettingsServiceTest() {}
9158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_ptr<syncer::SyncChangeProcessor> CreateSyncProcessor() {
9358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    sync_processor_ = new MockChangeProcessor();
9458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return scoped_ptr<syncer::SyncChangeProcessor>(sync_processor_);
9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void StartSyncing(const syncer::SyncDataList& initial_sync_data) {
9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    scoped_ptr<syncer::SyncErrorFactory> error_handler(
9958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        new MockSyncErrorFactory(syncer::MANAGED_USER_SETTINGS));
10058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    syncer::SyncMergeResult result = settings_service_.MergeDataAndStartSyncing(
10158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        syncer::MANAGED_USER_SETTINGS,
10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        initial_sync_data,
10358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        CreateSyncProcessor(),
10458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        error_handler.Pass());
10558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_FALSE(result.error().IsSet());
10658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void UploadSplitItem(const std::string& key, const std::string& value) {
10958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    split_items_.SetStringWithoutPathExpansion(key, value);
11058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    settings_service_.UploadItem(
11158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        ManagedUserSettingsService::MakeSplitSettingKey(kSplitItemName,
11258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                                            key),
11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        scoped_ptr<base::Value>(new base::StringValue(value)));
11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
11658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void UploadAtomicItem(const std::string& value) {
11758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    atomic_setting_value_.reset(new base::StringValue(value));
11858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    settings_service_.UploadItem(
11958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        kAtomicItemName,
12058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        scoped_ptr<base::Value>(new base::StringValue(value)));
12158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
12258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
12358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void VerifySyncDataItem(syncer::SyncData sync_data) {
12458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const sync_pb::ManagedUserSettingSpecifics& managed_user_setting =
12558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        sync_data.GetSpecifics().managed_user_setting();
12658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    base::Value* expected_value = NULL;
12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (managed_user_setting.name() == kAtomicItemName) {
12858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      expected_value = atomic_setting_value_.get();
12958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    } else {
13058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      EXPECT_TRUE(StartsWithASCII(managed_user_setting.name(),
13158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  std::string(kSplitItemName) + ':',
13258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  true));
13358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      std::string key =
13458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          managed_user_setting.name().substr(strlen(kSplitItemName) + 1);
13558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      EXPECT_TRUE(split_items_.GetWithoutPathExpansion(key, &expected_value));
13658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
13758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
13858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    scoped_ptr<Value> value(
13958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        base::JSONReader::Read(managed_user_setting.value()));
14058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_TRUE(expected_value->Equals(value.get()));
14158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
14258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
14358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void OnNewSettingsAvailable(const base::DictionaryValue* settings) {
14458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (!settings)
14558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      settings_.reset();
14658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    else
14758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      settings_.reset(settings->DeepCopy());
14858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
14958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
15058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // testing::Test overrides:
15158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
15258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    TestingPrefStore* pref_store = new TestingPrefStore;
15358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    settings_service_.Init(pref_store);
15458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    settings_service_.Subscribe(
15558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        base::Bind(&ManagedUserSettingsServiceTest::OnNewSettingsAvailable,
15658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                   base::Unretained(this)));
15758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    pref_store->SetInitializationCompleted();
15858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ASSERT_FALSE(settings_);
15958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    settings_service_.Activate();
16058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ASSERT_TRUE(settings_);
16158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
16258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void TearDown() OVERRIDE {
16458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    settings_service_.Shutdown();
16558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
16658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
16758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::DictionaryValue split_items_;
16858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_ptr<base::Value> atomic_setting_value_;
16958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ManagedUserSettingsService settings_service_;
17058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> settings_;
17158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
17258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Owned by the ManagedUserSettingsService.
17358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  MockChangeProcessor* sync_processor_;
17458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
17558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
17658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(ManagedUserSettingsServiceTest, ProcessAtomicSetting) {
17758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  StartSyncing(syncer::SyncDataList());
17858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(settings_);
17958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const base::Value* value = NULL;
18058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_FALSE(settings_->GetWithoutPathExpansion(kSettingsName, &value));
18158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
18258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  settings_.reset();
18358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  syncer::SyncData data =
18458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      ManagedUserSettingsService::CreateSyncDataForSetting(
18558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          kSettingsName, base::StringValue(kSettingsValue));
18658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  syncer::SyncChangeList change_list;
18758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  change_list.push_back(
18858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_ADD, data));
18958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  syncer::SyncError error =
19058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      settings_service_.ProcessSyncChanges(FROM_HERE, change_list);
19158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_FALSE(error.IsSet()) << error.ToString();
19258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(settings_);
19358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(settings_->GetWithoutPathExpansion(kSettingsName, &value));
19458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  std::string string_value;
19558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&string_value));
19658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ(kSettingsValue, string_value);
19758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
19858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
19958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(ManagedUserSettingsServiceTest, ProcessSplitSetting) {
20058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  StartSyncing(syncer::SyncDataList());
20158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(settings_);
20258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const base::Value* value = NULL;
20358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_FALSE(settings_->GetWithoutPathExpansion(kSettingsName, &value));
20458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
20558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::DictionaryValue dict;
20658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  dict.SetString("foo", "bar");
20758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  dict.SetBoolean("awesomesauce", true);
20858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  dict.SetInteger("eaudecologne", 4711);
20958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
21058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  settings_.reset();
21158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  syncer::SyncChangeList change_list;
21258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  for (base::DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) {
21358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    syncer::SyncData data =
21458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        ManagedUserSettingsService::CreateSyncDataForSetting(
21558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            ManagedUserSettingsService::MakeSplitSettingKey(kSettingsName,
21658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                                                it.key()),
21758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            it.value());
21858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    change_list.push_back(
21958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_ADD, data));
22058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
22158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  syncer::SyncError error =
22258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      settings_service_.ProcessSyncChanges(FROM_HERE, change_list);
22358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_FALSE(error.IsSet()) << error.ToString();
22458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(settings_);
22558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(settings_->GetWithoutPathExpansion(kSettingsName, &value));
22658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const base::DictionaryValue* dict_value = NULL;
22758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(value->GetAsDictionary(&dict_value));
22858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_TRUE(dict_value->Equals(&dict));
22958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
23058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
23158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(ManagedUserSettingsServiceTest, SetLocalSetting) {
23258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const base::Value* value = NULL;
23358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_FALSE(settings_->GetWithoutPathExpansion(kSettingsName, &value));
23458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
23558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  settings_.reset();
23658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  settings_service_.SetLocalSettingForTesting(
23758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      kSettingsName,
23858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      scoped_ptr<base::Value>(new base::StringValue(kSettingsValue)));
23958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(settings_);
24058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(settings_->GetWithoutPathExpansion(kSettingsName, &value));
24158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  std::string string_value;
24258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&string_value));
24358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ(kSettingsValue, string_value);
24458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
24558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
24658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(ManagedUserSettingsServiceTest, UploadItem) {
24758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  UploadSplitItem("foo", "bar");
24858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  UploadSplitItem("blurp", "baz");
24958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  UploadAtomicItem("hurdle");
25058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
25158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Uploading should produce changes when we start syncing.
25258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  StartSyncing(syncer::SyncDataList());
25358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const syncer::SyncChangeList& changes = sync_processor_->changes();
25458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_EQ(3u, changes.size());
25558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  for (syncer::SyncChangeList::const_iterator it = changes.begin();
25658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)       it != changes.end(); ++it) {
25758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ASSERT_TRUE(it->IsValid());
25858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_EQ(syncer::SyncChange::ACTION_ADD, it->change_type());
25958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    VerifySyncDataItem(it->sync_data());
26058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
26158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
26258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // It should also show up in local Sync data.
26358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  syncer::SyncDataList sync_data =
26458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      settings_service_.GetAllSyncData(syncer::MANAGED_USER_SETTINGS);
26558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ(3u, sync_data.size());
26658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  for (syncer::SyncDataList::const_iterator it = sync_data.begin();
26758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)       it != sync_data.end(); ++it) {
26858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    VerifySyncDataItem(*it);
26958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
27058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
27158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Uploading after we have started syncing should work too.
27258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  UploadSplitItem("froodle", "narf");
27358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_EQ(1u, sync_processor_->changes().size());
27458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  syncer::SyncChange change = sync_processor_->changes()[0];
27558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(change.IsValid());
27658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
27758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  VerifySyncDataItem(change.sync_data());
27858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
27958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  sync_data = settings_service_.GetAllSyncData(syncer::MANAGED_USER_SETTINGS);
28058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ(4u, sync_data.size());
28158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  for (syncer::SyncDataList::const_iterator it = sync_data.begin();
28258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)       it != sync_data.end(); ++it) {
28358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    VerifySyncDataItem(*it);
28458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
28558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
28658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Uploading an item with a previously seen key should create an UPDATE
28758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // action.
28858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  UploadSplitItem("blurp", "snarl");
28958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_EQ(1u, sync_processor_->changes().size());
29058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  change = sync_processor_->changes()[0];
29158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(change.IsValid());
29258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
29358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  VerifySyncDataItem(change.sync_data());
29458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
29558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  sync_data = settings_service_.GetAllSyncData(syncer::MANAGED_USER_SETTINGS);
29658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ(4u, sync_data.size());
29758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  for (syncer::SyncDataList::const_iterator it = sync_data.begin();
29858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)       it != sync_data.end(); ++it) {
29958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    VerifySyncDataItem(*it);
30058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
30158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
30258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  UploadAtomicItem("fjord");
30358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_EQ(1u, sync_processor_->changes().size());
30458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  change = sync_processor_->changes()[0];
30558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(change.IsValid());
30658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
30758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  VerifySyncDataItem(change.sync_data());
30858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
30958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  sync_data = settings_service_.GetAllSyncData(syncer::MANAGED_USER_SETTINGS);
31058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ(4u, sync_data.size());
31158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  for (syncer::SyncDataList::const_iterator it = sync_data.begin();
31258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)       it != sync_data.end(); ++it) {
31358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    VerifySyncDataItem(*it);
31458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
31558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
31658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // The uploaded items should not show up as settings.
31758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const base::Value* value = NULL;
31858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_FALSE(settings_->GetWithoutPathExpansion(kAtomicItemName, &value));
31958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_FALSE(settings_->GetWithoutPathExpansion(kSplitItemName, &value));
32058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
32158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Restarting sync should not create any new changes.
32258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  settings_service_.StopSyncing(syncer::MANAGED_USER_SETTINGS);
32358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  StartSyncing(sync_data);
32458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_EQ(0u, sync_processor_->changes().size());
32558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
326