// Copyright (c) 2012 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 <stddef.h>

#include <memory>
#include <utility>

#include "base/bind.h"
#include "base/files/scoped_temp_dir.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/memory/ptr_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/browser/extensions/api/storage/settings_sync_util.h"
#include "chrome/browser/extensions/api/storage/sync_value_store_cache.h"
#include "chrome/browser/extensions/api/storage/syncable_settings_storage.h"
#include "chrome/test/base/testing_profile.h"
#include "components/sync/model/sync_change_processor.h"
#include "components/sync/model/sync_change_processor_wrapper_for_test.h"
#include "components/sync/model/sync_error_factory.h"
#include "components/sync/model/sync_error_factory_mock.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h"
#include "extensions/browser/api/storage/backend_task_runner.h"
#include "extensions/browser/api/storage/settings_test_util.h"
#include "extensions/browser/api/storage/storage_frontend.h"
#include "extensions/browser/event_router.h"
#include "extensions/browser/event_router_factory.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/mock_extension_system.h"
#include "extensions/browser/value_store/test_value_store_factory.h"
#include "extensions/browser/value_store/testing_value_store.h"
#include "extensions/common/manifest.h"
#include "testing/gtest/include/gtest/gtest.h"

using base::DictionaryValue;
using base::ListValue;
using base::Value;
namespace extensions {

namespace util = settings_test_util;

namespace {

// To save typing ValueStore::DEFAULTS everywhere.
const ValueStore::WriteOptions DEFAULTS = ValueStore::DEFAULTS;

// More saving typing. Maps extension IDs to a list of sync changes for that
// extension.
using SettingSyncDataMultimap =
    std::map<std::string, std::unique_ptr<SettingSyncDataList>>;

// Gets the pretty-printed JSON for a value.
static std::string GetJson(const base::Value& value) {
  std::string json;
  base::JSONWriter::WriteWithOptions(
      value, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json);
  return json;
}

// Returns whether two Values are equal.
testing::AssertionResult ValuesEq(
    const char* _1, const char* _2,
    const base::Value* expected,
    const base::Value* actual) {
  if (expected == actual) {
    return testing::AssertionSuccess();
  }
  if (!expected && actual) {
    return testing::AssertionFailure() <<
        "Expected NULL, actual: " << GetJson(*actual);
  }
  if (expected && !actual) {
    return testing::AssertionFailure() <<
        "Expected: " << GetJson(*expected) << ", actual NULL";
  }
  if (!expected->Equals(actual)) {
    return testing::AssertionFailure() <<
        "Expected: " << GetJson(*expected) << ", actual: " << GetJson(*actual);
  }
  return testing::AssertionSuccess();
}

// Returns whether the result of a storage operation is an expected value.
// Logs when different.
testing::AssertionResult SettingsEq(
    const char* _1, const char* _2,
    const base::DictionaryValue& expected,
    ValueStore::ReadResult actual) {
  if (!actual->status().ok()) {
    return testing::AssertionFailure()
           << "Expected: " << expected
           << ", actual has error: " << actual->status().message;
  }
  return ValuesEq(_1, _2, &expected, &actual->settings());
}

// SyncChangeProcessor which just records the changes made, accessed after
// being converted to the more useful SettingSyncData via changes().
class MockSyncChangeProcessor : public syncer::SyncChangeProcessor {
 public:
  MockSyncChangeProcessor() : fail_all_requests_(false) {}

  // syncer::SyncChangeProcessor implementation.
  syncer::SyncError ProcessSyncChanges(
      const base::Location& from_here,
      const syncer::SyncChangeList& change_list) override {
    if (fail_all_requests_) {
      return syncer::SyncError(
          FROM_HERE,
          syncer::SyncError::DATATYPE_ERROR,
          "MockSyncChangeProcessor: configured to fail",
          change_list[0].sync_data().GetDataType());
    }
    for (syncer::SyncChangeList::const_iterator it = change_list.begin();
        it != change_list.end(); ++it) {
      changes_.push_back(base::MakeUnique<SettingSyncData>(*it));
    }
    return syncer::SyncError();
  }

  syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const override {
    return syncer::SyncDataList();
  }

  // Mock methods.

  const SettingSyncDataList& changes() { return changes_; }

  void ClearChanges() {
    changes_.clear();
  }

  void set_fail_all_requests(bool fail_all_requests) {
    fail_all_requests_ = fail_all_requests;
  }

  // Returns the only change for a given extension setting.  If there is not
  // exactly 1 change for that key, a test assertion will fail.
  SettingSyncData* GetOnlyChange(const std::string& extension_id,
                                 const std::string& key) {
    std::vector<SettingSyncData*> matching_changes;
    for (const std::unique_ptr<SettingSyncData>& change : changes_) {
      if (change->extension_id() == extension_id && change->key() == key)
        matching_changes.push_back(change.get());
    }
    if (matching_changes.empty()) {
      ADD_FAILURE() << "No matching changes for " << extension_id << "/" <<
          key << " (out of " << changes_.size() << ")";
      return nullptr;
    }
    if (matching_changes.size() != 1u) {
      ADD_FAILURE() << matching_changes.size() << " matching changes for " <<
           extension_id << "/" << key << " (out of " << changes_.size() << ")";
    }
    return matching_changes[0];
  }

 private:
  SettingSyncDataList changes_;
  bool fail_all_requests_;
};

std::unique_ptr<KeyedService> MockExtensionSystemFactoryFunction(
    content::BrowserContext* context) {
  return base::MakeUnique<MockExtensionSystem>(context);
}

std::unique_ptr<KeyedService> BuildEventRouter(
    content::BrowserContext* profile) {
  return base::MakeUnique<extensions::EventRouter>(profile, nullptr);
}

}  // namespace

class ExtensionSettingsSyncTest : public testing::Test {
 public:
  ExtensionSettingsSyncTest()
      : storage_factory_(new TestValueStoreFactory()),
        sync_processor_(new MockSyncChangeProcessor),
        sync_processor_wrapper_(new syncer::SyncChangeProcessorWrapperForTest(
            sync_processor_.get())) {}

  void SetUp() override {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    profile_.reset(new TestingProfile(temp_dir_.GetPath()));
    storage_factory_->Reset();
    frontend_ =
        StorageFrontend::CreateForTesting(storage_factory_, profile_.get());

    ExtensionsBrowserClient::Get()
        ->GetExtensionSystemFactory()
        ->SetTestingFactoryAndUse(profile_.get(),
                                  &MockExtensionSystemFactoryFunction);

    EventRouterFactory::GetInstance()->SetTestingFactory(profile_.get(),
                                                         &BuildEventRouter);
  }

  void TearDown() override {
    frontend_.reset();
    profile_.reset();
    // Execute any pending deletion tasks.
    content::RunAllTasksUntilIdle();
  }

 protected:
  // Adds a record of an extension or app to the extension service, then returns
  // its storage area.
  ValueStore* AddExtensionAndGetStorage(
      const std::string& id, Manifest::Type type) {
    scoped_refptr<const Extension> extension =
        util::AddExtensionWithId(profile_.get(), id, type);
    return util::GetStorage(extension, frontend_.get());
  }

  // Gets the syncer::SyncableService for the given sync type.
  syncer::SyncableService* GetSyncableService(syncer::ModelType model_type) {
    SyncValueStoreCache* sync_cache = static_cast<SyncValueStoreCache*>(
        frontend_->GetValueStoreCache(settings_namespace::SYNC));
    return sync_cache->GetSyncableService(model_type);
  }

  // Gets all the sync data from the SyncableService for a sync type as a map
  // from extension id to its sync data.
  SettingSyncDataMultimap GetAllSyncData(syncer::ModelType model_type) {
    syncer::SyncDataList as_list =
        GetSyncableService(model_type)->GetAllSyncData(model_type);
    SettingSyncDataMultimap as_map;
    for (syncer::SyncDataList::iterator it = as_list.begin();
        it != as_list.end(); ++it) {
      std::unique_ptr<SettingSyncData> sync_data(new SettingSyncData(*it));
      std::unique_ptr<SettingSyncDataList>& list_for_extension =
          as_map[sync_data->extension_id()];
      if (!list_for_extension)
        list_for_extension.reset(new SettingSyncDataList());
      list_for_extension->push_back(std::move(sync_data));
    }
    return as_map;
  }

  // This class uses it's TestingValueStore in such a way that it always mints
  // new TestingValueStore instances.
  TestingValueStore* GetExisting(const ExtensionId& extension_id) {
    return static_cast<TestingValueStore*>(
        storage_factory_->GetExisting(extension_id));
  }

  template <typename Func>
  static void RunFunc(Func func) {
    func();
  }

  template <typename Func>
  void PostOnBackendSequenceAndWait(const base::Location& from_here,
                                    Func func) {
    GetBackendTaskRunner()->PostTask(
        from_here, base::Bind(&ExtensionSettingsSyncTest::RunFunc<Func>, func));
    content::RunAllTasksUntilIdle();
  }

  // Needed so that the DCHECKs for running on FILE or UI threads pass.
  content::TestBrowserThreadBundle test_browser_thread_bundle_;

  base::ScopedTempDir temp_dir_;
  std::unique_ptr<TestingProfile> profile_;
  std::unique_ptr<StorageFrontend> frontend_;
  scoped_refptr<TestValueStoreFactory> storage_factory_;
  std::unique_ptr<MockSyncChangeProcessor> sync_processor_;
  std::unique_ptr<syncer::SyncChangeProcessorWrapperForTest>
      sync_processor_wrapper_;
};

// Get a semblance of coverage for both EXTENSION_SETTINGS and APP_SETTINGS
// sync by roughly alternative which one to test.

TEST_F(ExtensionSettingsSyncTest, NoDataDoesNotInvokeSync) {
  syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
  Manifest::Type type = Manifest::TYPE_EXTENSION;

  PostOnBackendSequenceAndWait(FROM_HERE, [&, this]() {
    EXPECT_EQ(0u, GetAllSyncData(model_type).size());
  });

  // Have one extension created before sync is set up, the other created after.
  AddExtensionAndGetStorage("s1", type);

  PostOnBackendSequenceAndWait(FROM_HERE, [&, this]() {
    EXPECT_EQ(0u, GetAllSyncData(model_type).size());

    GetSyncableService(model_type)
        ->MergeDataAndStartSyncing(
            model_type, syncer::SyncDataList(),
            std::move(sync_processor_wrapper_),
            base::MakeUnique<syncer::SyncErrorFactoryMock>());
  });

  AddExtensionAndGetStorage("s2", type);

  PostOnBackendSequenceAndWait(FROM_HERE, [&, this]() {
    EXPECT_EQ(0u, GetAllSyncData(model_type).size());

    GetSyncableService(model_type)->StopSyncing(model_type);

    EXPECT_EQ(0u, sync_processor_->changes().size());
    EXPECT_EQ(0u, GetAllSyncData(model_type).size());
  });
}

TEST_F(ExtensionSettingsSyncTest, InSyncDataDoesNotInvokeSync) {
  syncer::ModelType model_type = syncer::APP_SETTINGS;
  Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;

  base::Value value1("fooValue");
  base::ListValue value2;
  value2.AppendString("barValue");

  ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
  ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);

  PostOnBackendSequenceAndWait(FROM_HERE, [&, this]() {
    storage1->Set(DEFAULTS, "foo", value1);
    storage2->Set(DEFAULTS, "bar", value2);

    SettingSyncDataMultimap all_sync_data = GetAllSyncData(model_type);
    EXPECT_EQ(2u, all_sync_data.size());
    EXPECT_EQ(1u, all_sync_data["s1"]->size());
    EXPECT_PRED_FORMAT2(ValuesEq, &value1, &(*all_sync_data["s1"])[0]->value());
    EXPECT_EQ(1u, all_sync_data["s2"]->size());
    EXPECT_PRED_FORMAT2(ValuesEq, &value2, &(*all_sync_data["s2"])[0]->value());

    syncer::SyncDataList sync_data;
    sync_data.push_back(
        settings_sync_util::CreateData("s1", "foo", value1, model_type));
    sync_data.push_back(
        settings_sync_util::CreateData("s2", "bar", value2, model_type));

    GetSyncableService(model_type)
        ->MergeDataAndStartSyncing(
            model_type, sync_data, std::move(sync_processor_wrapper_),
            base::MakeUnique<syncer::SyncErrorFactoryMock>());

    // Already in sync, so no changes.
    EXPECT_EQ(0u, sync_processor_->changes().size());

    // Regression test: not-changing the synced value shouldn't result in a sync
    // change, and changing the synced value should result in an update.
    storage1->Set(DEFAULTS, "foo", value1);
    EXPECT_EQ(0u, sync_processor_->changes().size());

    storage1->Set(DEFAULTS, "foo", value2);
    EXPECT_EQ(1u, sync_processor_->changes().size());
    SettingSyncData* change = sync_processor_->GetOnlyChange("s1", "foo");
    EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change->change_type());
    EXPECT_TRUE(value2.Equals(&change->value()));

    GetSyncableService(model_type)->StopSyncing(model_type);
  });
}

TEST_F(ExtensionSettingsSyncTest, LocalDataWithNoSyncDataIsPushedToSync) {
  syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
  Manifest::Type type = Manifest::TYPE_EXTENSION;

  base::Value value1("fooValue");
  base::ListValue value2;
  value2.AppendString("barValue");

  ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
  ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);

  PostOnBackendSequenceAndWait(FROM_HERE, [&, this]() {
    storage1->Set(DEFAULTS, "foo", value1);
    storage2->Set(DEFAULTS, "bar", value2);

    GetSyncableService(model_type)
        ->MergeDataAndStartSyncing(
            model_type, syncer::SyncDataList(),
            std::move(sync_processor_wrapper_),
            base::MakeUnique<syncer::SyncErrorFactoryMock>());

    // All settings should have been pushed to sync.
    EXPECT_EQ(2u, sync_processor_->changes().size());
    SettingSyncData* change = sync_processor_->GetOnlyChange("s1", "foo");
    EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change->change_type());
    EXPECT_TRUE(value1.Equals(&change->value()));
    change = sync_processor_->GetOnlyChange("s2", "bar");
    EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change->change_type());
    EXPECT_TRUE(value2.Equals(&change->value()));

    GetSyncableService(model_type)->StopSyncing(model_type);
  });
}

TEST_F(ExtensionSettingsSyncTest, AnySyncDataOverwritesLocalData) {
  syncer::ModelType model_type = syncer::APP_SETTINGS;
  Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;

  base::Value value1("fooValue");
  base::ListValue value2;
  value2.AppendString("barValue");

  // Maintain dictionaries mirrored to the expected values of the settings in
  // each storage area.
  base::DictionaryValue expected1, expected2;

  // Pre-populate one of the storage areas.
  ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);

  PostOnBackendSequenceAndWait(FROM_HERE, [&, this]() {
    storage1->Set(DEFAULTS, "overwriteMe", value1);

    syncer::SyncDataList sync_data;
    sync_data.push_back(
        settings_sync_util::CreateData("s1", "foo", value1, model_type));
    sync_data.push_back(
        settings_sync_util::CreateData("s2", "bar", value2, model_type));
    GetSyncableService(model_type)
        ->MergeDataAndStartSyncing(
            model_type, sync_data, std::move(sync_processor_wrapper_),
            base::MakeUnique<syncer::SyncErrorFactoryMock>());
    expected1.Set("foo", value1.CreateDeepCopy());
    expected2.Set("bar", value2.CreateDeepCopy());
  });

  ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);

  PostOnBackendSequenceAndWait(FROM_HERE, [&, this]() {
    // All changes should be local, so no sync changes.
    EXPECT_EQ(0u, sync_processor_->changes().size());

    // Sync settings should have been pushed to local settings.
    EXPECT_PRED_FORMAT2(SettingsEq, expected1, storage1->Get());
    EXPECT_PRED_FORMAT2(SettingsEq, expected2, storage2->Get());

    GetSyncableService(model_type)->StopSyncing(model_type);
  });
}

TEST_F(ExtensionSettingsSyncTest, ProcessSyncChanges) {
  syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
  Manifest::Type type = Manifest::TYPE_EXTENSION;

  base::Value value1("fooValue");
  base::ListValue value2;
  value2.AppendString("barValue");

  // Make storage1 initialised from local data, storage2 initialised from sync.
  ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
  ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);

  PostOnBackendSequenceAndWait(FROM_HERE, [&, this]() {
    // Maintain dictionaries mirrored to the expected values of the settings in
    // each storage area.
    base::DictionaryValue expected1, expected2;

    storage1->Set(DEFAULTS, "foo", value1);
    expected1.Set("foo", value1.CreateDeepCopy());

    syncer::SyncDataList sync_data;
    sync_data.push_back(
        settings_sync_util::CreateData("s2", "bar", value2, model_type));

    GetSyncableService(model_type)
        ->MergeDataAndStartSyncing(
            model_type, sync_data, std::move(sync_processor_wrapper_),
            base::MakeUnique<syncer::SyncErrorFactoryMock>());
    expected2.Set("bar", value2.CreateDeepCopy());

    // Make sync add some settings.
    syncer::SyncChangeList change_list;
    change_list.push_back(
        settings_sync_util::CreateAdd("s1", "bar", value2, model_type));
    change_list.push_back(
        settings_sync_util::CreateAdd("s2", "foo", value1, model_type));
    GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
    expected1.Set("bar", value2.CreateDeepCopy());
    expected2.Set("foo", value1.CreateDeepCopy());

    EXPECT_PRED_FORMAT2(SettingsEq, expected1, storage1->Get());
    EXPECT_PRED_FORMAT2(SettingsEq, expected2, storage2->Get());

    // Make sync update some settings, storage1 the new setting, storage2 the
    // initial setting.
    change_list.clear();
    change_list.push_back(
        settings_sync_util::CreateUpdate("s1", "bar", value2, model_type));
    change_list.push_back(
        settings_sync_util::CreateUpdate("s2", "bar", value1, model_type));
    GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
    expected1.Set("bar", value2.CreateDeepCopy());
    expected2.Set("bar", value1.CreateDeepCopy());

    EXPECT_PRED_FORMAT2(SettingsEq, expected1, storage1->Get());
    EXPECT_PRED_FORMAT2(SettingsEq, expected2, storage2->Get());

    // Make sync remove some settings, storage1 the initial setting, storage2
    // the new setting.
    change_list.clear();
    change_list.push_back(
        settings_sync_util::CreateDelete("s1", "foo", model_type));
    change_list.push_back(
        settings_sync_util::CreateDelete("s2", "foo", model_type));
    GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
    expected1.Remove("foo", NULL);
    expected2.Remove("foo", NULL);

    EXPECT_PRED_FORMAT2(SettingsEq, expected1, storage1->Get());
    EXPECT_PRED_FORMAT2(SettingsEq, expected2, storage2->Get());

    GetSyncableService(model_type)->StopSyncing(model_type);
  });
}

TEST_F(ExtensionSettingsSyncTest, PushToSync) {
  syncer::ModelType model_type = syncer::APP_SETTINGS;
  Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;

  base::Value value1("fooValue");
  base::ListValue value2;
  value2.AppendString("barValue");

  // Make storage1/2 initialised from local data, storage3/4 initialised from
  // sync.
  ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
  ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
  ValueStore* storage3 = AddExtensionAndGetStorage("s3", type);
  ValueStore* storage4 = AddExtensionAndGetStorage("s4", type);

  PostOnBackendSequenceAndWait(FROM_HERE, [&, this]() {
    storage1->Set(DEFAULTS, "foo", value1);
    storage2->Set(DEFAULTS, "foo", value1);

    syncer::SyncDataList sync_data;
    sync_data.push_back(
        settings_sync_util::CreateData("s3", "bar", value2, model_type));
    sync_data.push_back(
        settings_sync_util::CreateData("s4", "bar", value2, model_type));

    GetSyncableService(model_type)
        ->MergeDataAndStartSyncing(
            model_type, sync_data, std::move(sync_processor_wrapper_),
            base::MakeUnique<syncer::SyncErrorFactoryMock>());

    // Add something locally.
    storage1->Set(DEFAULTS, "bar", value2);
    storage2->Set(DEFAULTS, "bar", value2);
    storage3->Set(DEFAULTS, "foo", value1);
    storage4->Set(DEFAULTS, "foo", value1);

    SettingSyncData* change = sync_processor_->GetOnlyChange("s1", "bar");
    EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change->change_type());
    EXPECT_TRUE(value2.Equals(&change->value()));
    sync_processor_->GetOnlyChange("s2", "bar");
    EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change->change_type());
    EXPECT_TRUE(value2.Equals(&change->value()));
    change = sync_processor_->GetOnlyChange("s3", "foo");
    EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change->change_type());
    EXPECT_TRUE(value1.Equals(&change->value()));
    change = sync_processor_->GetOnlyChange("s4", "foo");
    EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change->change_type());
    EXPECT_TRUE(value1.Equals(&change->value()));

    // Change something locally, storage1/3 the new setting and storage2/4 the
    // initial setting, for all combinations of local vs sync intialisation and
    // new vs initial.
    sync_processor_->ClearChanges();
    storage1->Set(DEFAULTS, "bar", value1);
    storage2->Set(DEFAULTS, "foo", value2);
    storage3->Set(DEFAULTS, "bar", value1);
    storage4->Set(DEFAULTS, "foo", value2);

    change = sync_processor_->GetOnlyChange("s1", "bar");
    EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change->change_type());
    EXPECT_TRUE(value1.Equals(&change->value()));
    change = sync_processor_->GetOnlyChange("s2", "foo");
    EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change->change_type());
    EXPECT_TRUE(value2.Equals(&change->value()));
    change = sync_processor_->GetOnlyChange("s3", "bar");
    EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change->change_type());
    EXPECT_TRUE(value1.Equals(&change->value()));
    change = sync_processor_->GetOnlyChange("s4", "foo");
    EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change->change_type());
    EXPECT_TRUE(value2.Equals(&change->value()));

    // Remove something locally, storage1/3 the new setting and storage2/4 the
    // initial setting, for all combinations of local vs sync intialisation and
    // new vs initial.
    sync_processor_->ClearChanges();
    storage1->Remove("foo");
    storage2->Remove("bar");
    storage3->Remove("foo");
    storage4->Remove("bar");

    EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
              sync_processor_->GetOnlyChange("s1", "foo")->change_type());
    EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
              sync_processor_->GetOnlyChange("s2", "bar")->change_type());
    EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
              sync_processor_->GetOnlyChange("s3", "foo")->change_type());
    EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
              sync_processor_->GetOnlyChange("s4", "bar")->change_type());

    // Remove some nonexistent settings.
    sync_processor_->ClearChanges();
    storage1->Remove("foo");
    storage2->Remove("bar");
    storage3->Remove("foo");
    storage4->Remove("bar");

    EXPECT_EQ(0u, sync_processor_->changes().size());

    // Clear the rest of the settings.  Add the removed ones back first so that
    // more than one setting is cleared.
    storage1->Set(DEFAULTS, "foo", value1);
    storage2->Set(DEFAULTS, "bar", value2);
    storage3->Set(DEFAULTS, "foo", value1);
    storage4->Set(DEFAULTS, "bar", value2);

    sync_processor_->ClearChanges();
    storage1->Clear();
    storage2->Clear();
    storage3->Clear();
    storage4->Clear();

    EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
              sync_processor_->GetOnlyChange("s1", "foo")->change_type());
    EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
              sync_processor_->GetOnlyChange("s1", "bar")->change_type());
    EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
              sync_processor_->GetOnlyChange("s2", "foo")->change_type());
    EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
              sync_processor_->GetOnlyChange("s2", "bar")->change_type());
    EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
              sync_processor_->GetOnlyChange("s3", "foo")->change_type());
    EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
              sync_processor_->GetOnlyChange("s3", "bar")->change_type());
    EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
              sync_processor_->GetOnlyChange("s4", "foo")->change_type());
    EXPECT_EQ(syncer::SyncChange::ACTION_DELETE,
              sync_processor_->GetOnlyChange("s4", "bar")->change_type());

    GetSyncableService(model_type)->StopSyncing(model_type);
  });
}

TEST_F(ExtensionSettingsSyncTest, ExtensionAndAppSettingsSyncSeparately) {
  base::Value value1("fooValue");
  base::ListValue value2;
  value2.AppendString("barValue");

  // storage1 is an extension, storage2 is an app.
  ValueStore* storage1 = AddExtensionAndGetStorage(
      "s1", Manifest::TYPE_EXTENSION);
  ValueStore* storage2 = AddExtensionAndGetStorage(
      "s2", Manifest::TYPE_LEGACY_PACKAGED_APP);

  PostOnBackendSequenceAndWait(FROM_HERE, [&, this]() {
    storage1->Set(DEFAULTS, "foo", value1);
    storage2->Set(DEFAULTS, "bar", value2);

    SettingSyncDataMultimap extension_sync_data =
        GetAllSyncData(syncer::EXTENSION_SETTINGS);
    EXPECT_EQ(1u, extension_sync_data.size());
    EXPECT_EQ(1u, extension_sync_data["s1"]->size());
    EXPECT_PRED_FORMAT2(ValuesEq, &value1,
                        &(*extension_sync_data["s1"])[0]->value());

    SettingSyncDataMultimap app_sync_data =
        GetAllSyncData(syncer::APP_SETTINGS);
    EXPECT_EQ(1u, app_sync_data.size());
    EXPECT_EQ(1u, app_sync_data["s2"]->size());
    EXPECT_PRED_FORMAT2(ValuesEq, &value2, &(*app_sync_data["s2"])[0]->value());

    // Stop each separately, there should be no changes either time.
    syncer::SyncDataList sync_data;
    sync_data.push_back(settings_sync_util::CreateData(
        "s1", "foo", value1, syncer::EXTENSION_SETTINGS));

    GetSyncableService(syncer::EXTENSION_SETTINGS)
        ->MergeDataAndStartSyncing(
            syncer::EXTENSION_SETTINGS, sync_data,
            std::move(sync_processor_wrapper_),
            base::MakeUnique<syncer::SyncErrorFactoryMock>());
    GetSyncableService(syncer::EXTENSION_SETTINGS)
        ->StopSyncing(syncer::EXTENSION_SETTINGS);
    EXPECT_EQ(0u, sync_processor_->changes().size());

    sync_data.clear();
    sync_data.push_back(settings_sync_util::CreateData("s2", "bar", value2,
                                                       syncer::APP_SETTINGS));

    std::unique_ptr<syncer::SyncChangeProcessorWrapperForTest>
        app_settings_delegate_(new syncer::SyncChangeProcessorWrapperForTest(
            sync_processor_.get()));
    GetSyncableService(syncer::APP_SETTINGS)
        ->MergeDataAndStartSyncing(
            syncer::APP_SETTINGS, sync_data, std::move(app_settings_delegate_),
            base::MakeUnique<syncer::SyncErrorFactoryMock>());
    GetSyncableService(syncer::APP_SETTINGS)->StopSyncing(syncer::APP_SETTINGS);
    EXPECT_EQ(0u, sync_processor_->changes().size());
  });
}

TEST_F(ExtensionSettingsSyncTest, FailingStartSyncingDisablesSync) {
  syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
  Manifest::Type type = Manifest::TYPE_EXTENSION;

  base::Value fooValue("fooValue");
  base::Value barValue("barValue");

  // There is a bit of a convoluted method to get storage areas that can fail;
  // hand out TestingValueStore object then toggle them failing/succeeding
  // as necessary.

  ValueStore* good = AddExtensionAndGetStorage("good", type);
  ValueStore* bad = AddExtensionAndGetStorage("bad", type);

  PostOnBackendSequenceAndWait(FROM_HERE, [&, this]() {
    // Make bad fail for incoming sync changes.
    GetExisting("bad")->set_status_code(ValueStore::CORRUPTION);
    {
      syncer::SyncDataList sync_data;
      sync_data.push_back(
          settings_sync_util::CreateData("good", "foo", fooValue, model_type));
      sync_data.push_back(
          settings_sync_util::CreateData("bad", "foo", fooValue, model_type));
      GetSyncableService(model_type)
          ->MergeDataAndStartSyncing(
              model_type, sync_data, std::move(sync_processor_wrapper_),
              base::MakeUnique<syncer::SyncErrorFactoryMock>());
    }
    GetExisting("bad")->set_status_code(ValueStore::OK);

    {
      base::DictionaryValue dict;
      dict.Set("foo", fooValue.CreateDeepCopy());
      EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
    }
    {
      base::DictionaryValue dict;
      EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
    }

    // Changes made to good should be sent to sync, changes from bad shouldn't.
    sync_processor_->ClearChanges();
    good->Set(DEFAULTS, "bar", barValue);
    bad->Set(DEFAULTS, "bar", barValue);

    EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
              sync_processor_->GetOnlyChange("good", "bar")->change_type());
    EXPECT_EQ(1u, sync_processor_->changes().size());

    {
      base::DictionaryValue dict;
      dict.Set("foo", fooValue.CreateDeepCopy());
      dict.Set("bar", barValue.CreateDeepCopy());
      EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
    }
    {
      base::DictionaryValue dict;
      dict.Set("bar", barValue.CreateDeepCopy());
      EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
    }

    // Changes received from sync should go to good but not bad (even when it's
    // not failing).
    {
      syncer::SyncChangeList change_list;
      change_list.push_back(settings_sync_util::CreateUpdate(
          "good", "foo", barValue, model_type));
      // (Sending UPDATE here even though it's adding, since that's what the
      // state of sync is.  In any case, it won't work.)
      change_list.push_back(
          settings_sync_util::CreateUpdate("bad", "foo", barValue, model_type));
      GetSyncableService(model_type)
          ->ProcessSyncChanges(FROM_HERE, change_list);
    }

    {
      base::DictionaryValue dict;
      dict.Set("foo", barValue.CreateDeepCopy());
      dict.Set("bar", barValue.CreateDeepCopy());
      EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
    }
    {
      base::DictionaryValue dict;
      dict.Set("bar", barValue.CreateDeepCopy());
      EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
    }

    // Changes made to bad still shouldn't go to sync, even though it didn't
    // fail last time.
    sync_processor_->ClearChanges();
    good->Set(DEFAULTS, "bar", fooValue);
    bad->Set(DEFAULTS, "bar", fooValue);

    EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
              sync_processor_->GetOnlyChange("good", "bar")->change_type());
    EXPECT_EQ(1u, sync_processor_->changes().size());

    {
      base::DictionaryValue dict;
      dict.Set("foo", barValue.CreateDeepCopy());
      dict.Set("bar", fooValue.CreateDeepCopy());
      EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
    }
    {
      base::DictionaryValue dict;
      dict.Set("bar", fooValue.CreateDeepCopy());
      EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
    }

    // Failing ProcessSyncChanges shouldn't go to the storage.
    GetExisting("bad")->set_status_code(ValueStore::CORRUPTION);
    {
      syncer::SyncChangeList change_list;
      change_list.push_back(settings_sync_util::CreateUpdate(
          "good", "foo", fooValue, model_type));
      // (Ditto.)
      change_list.push_back(
          settings_sync_util::CreateUpdate("bad", "foo", fooValue, model_type));
      GetSyncableService(model_type)
          ->ProcessSyncChanges(FROM_HERE, change_list);
    }
    GetExisting("bad")->set_status_code(ValueStore::OK);

    {
      base::DictionaryValue dict;
      dict.Set("foo", fooValue.CreateDeepCopy());
      dict.Set("bar", fooValue.CreateDeepCopy());
      EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
    }
    {
      base::DictionaryValue dict;
      dict.Set("bar", fooValue.CreateDeepCopy());
      EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
    }

    // Restarting sync should make bad start syncing again.
    sync_processor_->ClearChanges();
    GetSyncableService(model_type)->StopSyncing(model_type);
    sync_processor_wrapper_.reset(
        new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get()));
    GetSyncableService(model_type)
        ->MergeDataAndStartSyncing(
            model_type, syncer::SyncDataList(),
            std::move(sync_processor_wrapper_),
            base::MakeUnique<syncer::SyncErrorFactoryMock>());

    // Local settings will have been pushed to sync, since it's empty (in this
    // test; presumably it wouldn't be live, since we've been getting changes).
    EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
              sync_processor_->GetOnlyChange("good", "foo")->change_type());
    EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
              sync_processor_->GetOnlyChange("good", "bar")->change_type());
    EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
              sync_processor_->GetOnlyChange("bad", "bar")->change_type());
    EXPECT_EQ(3u, sync_processor_->changes().size());

    // Live local changes now get pushed, too.
    sync_processor_->ClearChanges();
    good->Set(DEFAULTS, "bar", barValue);
    bad->Set(DEFAULTS, "bar", barValue);

    EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
              sync_processor_->GetOnlyChange("good", "bar")->change_type());
    EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
              sync_processor_->GetOnlyChange("bad", "bar")->change_type());
    EXPECT_EQ(2u, sync_processor_->changes().size());

    // And ProcessSyncChanges work, too.
    {
      syncer::SyncChangeList change_list;
      change_list.push_back(settings_sync_util::CreateUpdate(
          "good", "bar", fooValue, model_type));
      change_list.push_back(
          settings_sync_util::CreateUpdate("bad", "bar", fooValue, model_type));
      GetSyncableService(model_type)
          ->ProcessSyncChanges(FROM_HERE, change_list);
    }

    {
      base::DictionaryValue dict;
      dict.Set("foo", fooValue.CreateDeepCopy());
      dict.Set("bar", fooValue.CreateDeepCopy());
      EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
    }
    {
      base::DictionaryValue dict;
      dict.Set("bar", fooValue.CreateDeepCopy());
      EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
    }
  });
}

TEST_F(ExtensionSettingsSyncTest, FailingProcessChangesDisablesSync) {
  // The test above tests a failing ProcessSyncChanges too, but here test with
  // an initially passing MergeDataAndStartSyncing.
  syncer::ModelType model_type = syncer::APP_SETTINGS;
  Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;

  base::Value fooValue("fooValue");
  base::Value barValue("barValue");

  ValueStore* good = AddExtensionAndGetStorage("good", type);
  ValueStore* bad = AddExtensionAndGetStorage("bad", type);

  PostOnBackendSequenceAndWait(FROM_HERE, [&, this]() {
    // Unlike before, initially succeeding MergeDataAndStartSyncing.
    {
      syncer::SyncDataList sync_data;
      sync_data.push_back(
          settings_sync_util::CreateData("good", "foo", fooValue, model_type));
      sync_data.push_back(
          settings_sync_util::CreateData("bad", "foo", fooValue, model_type));
      GetSyncableService(model_type)
          ->MergeDataAndStartSyncing(
              model_type, sync_data, std::move(sync_processor_wrapper_),
              base::MakeUnique<syncer::SyncErrorFactoryMock>());
    }

    EXPECT_EQ(0u, sync_processor_->changes().size());

    {
      base::DictionaryValue dict;
      dict.Set("foo", fooValue.CreateDeepCopy());
      EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
    }
    {
      base::DictionaryValue dict;
      dict.Set("foo", fooValue.CreateDeepCopy());
      EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
    }

    // Now fail ProcessSyncChanges for bad.
    GetExisting("bad")->set_status_code(ValueStore::CORRUPTION);
    {
      syncer::SyncChangeList change_list;
      change_list.push_back(
          settings_sync_util::CreateAdd("good", "bar", barValue, model_type));
      change_list.push_back(
          settings_sync_util::CreateAdd("bad", "bar", barValue, model_type));
      GetSyncableService(model_type)
          ->ProcessSyncChanges(FROM_HERE, change_list);
    }
    GetExisting("bad")->set_status_code(ValueStore::OK);

    {
      base::DictionaryValue dict;
      dict.Set("foo", fooValue.CreateDeepCopy());
      dict.Set("bar", barValue.CreateDeepCopy());
      EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
    }
    {
      base::DictionaryValue dict;
      dict.Set("foo", fooValue.CreateDeepCopy());
      EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
    }

    // No more changes sent to sync for bad.
    sync_processor_->ClearChanges();
    good->Set(DEFAULTS, "foo", barValue);
    bad->Set(DEFAULTS, "foo", barValue);

    EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
              sync_processor_->GetOnlyChange("good", "foo")->change_type());
    EXPECT_EQ(1u, sync_processor_->changes().size());

    // No more changes received from sync should go to bad.
    {
      syncer::SyncChangeList change_list;
      change_list.push_back(
          settings_sync_util::CreateAdd("good", "foo", fooValue, model_type));
      change_list.push_back(
          settings_sync_util::CreateAdd("bad", "foo", fooValue, model_type));
      GetSyncableService(model_type)
          ->ProcessSyncChanges(FROM_HERE, change_list);
    }

    {
      base::DictionaryValue dict;
      dict.Set("foo", fooValue.CreateDeepCopy());
      dict.Set("bar", barValue.CreateDeepCopy());
      EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
    }
    {
      base::DictionaryValue dict;
      dict.Set("foo", barValue.CreateDeepCopy());
      EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
    }
  });
}

TEST_F(ExtensionSettingsSyncTest, FailingGetAllSyncDataDoesntStopSync) {
  syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
  Manifest::Type type = Manifest::TYPE_EXTENSION;

  base::Value fooValue("fooValue");
  base::Value barValue("barValue");

  ValueStore* good = AddExtensionAndGetStorage("good", type);
  ValueStore* bad = AddExtensionAndGetStorage("bad", type);

  PostOnBackendSequenceAndWait(FROM_HERE, [&, this]() {
    good->Set(DEFAULTS, "foo", fooValue);
    bad->Set(DEFAULTS, "foo", fooValue);

    // Even though bad will fail to get all sync data, sync data should still
    // include that from good.
    GetExisting("bad")->set_status_code(ValueStore::CORRUPTION);
    {
      syncer::SyncDataList all_sync_data =
          GetSyncableService(model_type)->GetAllSyncData(model_type);
      EXPECT_EQ(1u, all_sync_data.size());
      EXPECT_EQ("good/foo", syncer::SyncDataLocal(all_sync_data[0]).GetTag());
    }
    GetExisting("bad")->set_status_code(ValueStore::OK);

    // Sync shouldn't be disabled for good (nor bad -- but this is unimportant).
    GetSyncableService(model_type)
        ->MergeDataAndStartSyncing(
            model_type, syncer::SyncDataList(),
            std::move(sync_processor_wrapper_),
            base::MakeUnique<syncer::SyncErrorFactoryMock>());

    EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
              sync_processor_->GetOnlyChange("good", "foo")->change_type());
    EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
              sync_processor_->GetOnlyChange("bad", "foo")->change_type());
    EXPECT_EQ(2u, sync_processor_->changes().size());

    sync_processor_->ClearChanges();
    good->Set(DEFAULTS, "bar", barValue);
    bad->Set(DEFAULTS, "bar", barValue);

    EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
              sync_processor_->GetOnlyChange("good", "bar")->change_type());
    EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
              sync_processor_->GetOnlyChange("bad", "bar")->change_type());
    EXPECT_EQ(2u, sync_processor_->changes().size());
  });
}

TEST_F(ExtensionSettingsSyncTest, FailureToReadChangesToPushDisablesSync) {
  syncer::ModelType model_type = syncer::APP_SETTINGS;
  Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;

  base::Value fooValue("fooValue");
  base::Value barValue("barValue");

  ValueStore* good = AddExtensionAndGetStorage("good", type);
  ValueStore* bad = AddExtensionAndGetStorage("bad", type);

  PostOnBackendSequenceAndWait(FROM_HERE, [&, this]() {
    good->Set(DEFAULTS, "foo", fooValue);
    bad->Set(DEFAULTS, "foo", fooValue);

    // good will successfully push foo:fooValue to sync, but bad will fail to
    // get them so won't.
    GetExisting("bad")->set_status_code(ValueStore::CORRUPTION);
    GetSyncableService(model_type)
        ->MergeDataAndStartSyncing(
            model_type, syncer::SyncDataList(),
            std::move(sync_processor_wrapper_),
            base::MakeUnique<syncer::SyncErrorFactoryMock>());
    GetExisting("bad")->set_status_code(ValueStore::OK);

    EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
              sync_processor_->GetOnlyChange("good", "foo")->change_type());
    EXPECT_EQ(1u, sync_processor_->changes().size());

    // bad should now be disabled for sync.
    sync_processor_->ClearChanges();
    good->Set(DEFAULTS, "bar", barValue);
    bad->Set(DEFAULTS, "bar", barValue);

    EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
              sync_processor_->GetOnlyChange("good", "bar")->change_type());
    EXPECT_EQ(1u, sync_processor_->changes().size());

    {
      syncer::SyncChangeList change_list;
      change_list.push_back(settings_sync_util::CreateUpdate(
          "good", "foo", barValue, model_type));
      // (Sending ADD here even though it's updating, since that's what the
      // state of sync is.  In any case, it won't work.)
      change_list.push_back(
          settings_sync_util::CreateAdd("bad", "foo", barValue, model_type));
      GetSyncableService(model_type)
          ->ProcessSyncChanges(FROM_HERE, change_list);
    }

    {
      base::DictionaryValue dict;
      dict.Set("foo", barValue.CreateDeepCopy());
      dict.Set("bar", barValue.CreateDeepCopy());
      EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
    }
    {
      base::DictionaryValue dict;
      dict.Set("foo", fooValue.CreateDeepCopy());
      dict.Set("bar", barValue.CreateDeepCopy());
      EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
    }

    // Re-enabling sync without failing should cause the local changes from bad
    // to be pushed to sync successfully, as should future changes to bad.
    sync_processor_->ClearChanges();
    GetSyncableService(model_type)->StopSyncing(model_type);
    sync_processor_wrapper_.reset(
        new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get()));
    GetSyncableService(model_type)
        ->MergeDataAndStartSyncing(
            model_type, syncer::SyncDataList(),
            std::move(sync_processor_wrapper_),
            base::MakeUnique<syncer::SyncErrorFactoryMock>());

    EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
              sync_processor_->GetOnlyChange("good", "foo")->change_type());
    EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
              sync_processor_->GetOnlyChange("good", "bar")->change_type());
    EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
              sync_processor_->GetOnlyChange("bad", "foo")->change_type());
    EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
              sync_processor_->GetOnlyChange("bad", "bar")->change_type());
    EXPECT_EQ(4u, sync_processor_->changes().size());

    sync_processor_->ClearChanges();
    good->Set(DEFAULTS, "bar", fooValue);
    bad->Set(DEFAULTS, "bar", fooValue);

    EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
              sync_processor_->GetOnlyChange("good", "bar")->change_type());
    EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
              sync_processor_->GetOnlyChange("good", "bar")->change_type());
    EXPECT_EQ(2u, sync_processor_->changes().size());
  });
}

TEST_F(ExtensionSettingsSyncTest, FailureToPushLocalStateDisablesSync) {
  syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
  Manifest::Type type = Manifest::TYPE_EXTENSION;

  base::Value fooValue("fooValue");
  base::Value barValue("barValue");

  ValueStore* good = AddExtensionAndGetStorage("good", type);
  ValueStore* bad = AddExtensionAndGetStorage("bad", type);

  PostOnBackendSequenceAndWait(FROM_HERE, [&, this]() {
    // Only set bad; setting good will cause it to fail below.
    bad->Set(DEFAULTS, "foo", fooValue);

    sync_processor_->set_fail_all_requests(true);
    GetSyncableService(model_type)
        ->MergeDataAndStartSyncing(
            model_type, syncer::SyncDataList(),
            std::move(sync_processor_wrapper_),
            base::MakeUnique<syncer::SyncErrorFactoryMock>());
    sync_processor_->set_fail_all_requests(false);

    // Changes from good will be send to sync, changes from bad won't.
    sync_processor_->ClearChanges();
    good->Set(DEFAULTS, "foo", barValue);
    bad->Set(DEFAULTS, "foo", barValue);

    EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
              sync_processor_->GetOnlyChange("good", "foo")->change_type());
    EXPECT_EQ(1u, sync_processor_->changes().size());

    // Changes from sync will be sent to good, not to bad.
    {
      syncer::SyncChangeList change_list;
      change_list.push_back(
          settings_sync_util::CreateAdd("good", "bar", barValue, model_type));
      change_list.push_back(
          settings_sync_util::CreateAdd("bad", "bar", barValue, model_type));
      GetSyncableService(model_type)
          ->ProcessSyncChanges(FROM_HERE, change_list);
    }

    {
      base::DictionaryValue dict;
      dict.Set("foo", barValue.CreateDeepCopy());
      dict.Set("bar", barValue.CreateDeepCopy());
      EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
    }
    {
      base::DictionaryValue dict;
      dict.Set("foo", barValue.CreateDeepCopy());
      EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
    }

    // Restarting sync makes everything work again.
    sync_processor_->ClearChanges();
    GetSyncableService(model_type)->StopSyncing(model_type);
    sync_processor_wrapper_.reset(
        new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get()));
    GetSyncableService(model_type)
        ->MergeDataAndStartSyncing(
            model_type, syncer::SyncDataList(),
            std::move(sync_processor_wrapper_),
            base::MakeUnique<syncer::SyncErrorFactoryMock>());

    EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
              sync_processor_->GetOnlyChange("good", "foo")->change_type());
    EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
              sync_processor_->GetOnlyChange("good", "bar")->change_type());
    EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
              sync_processor_->GetOnlyChange("bad", "foo")->change_type());
    EXPECT_EQ(3u, sync_processor_->changes().size());

    sync_processor_->ClearChanges();
    good->Set(DEFAULTS, "foo", fooValue);
    bad->Set(DEFAULTS, "foo", fooValue);

    EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
              sync_processor_->GetOnlyChange("good", "foo")->change_type());
    EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
              sync_processor_->GetOnlyChange("good", "foo")->change_type());
    EXPECT_EQ(2u, sync_processor_->changes().size());
  });
}

TEST_F(ExtensionSettingsSyncTest, FailureToPushLocalChangeDisablesSync) {
  syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
  Manifest::Type type = Manifest::TYPE_EXTENSION;

  base::Value fooValue("fooValue");
  base::Value barValue("barValue");

  ValueStore* good = AddExtensionAndGetStorage("good", type);
  ValueStore* bad = AddExtensionAndGetStorage("bad", type);

  PostOnBackendSequenceAndWait(FROM_HERE, [&, this]() {
    GetSyncableService(model_type)
        ->MergeDataAndStartSyncing(
            model_type, syncer::SyncDataList(),
            std::move(sync_processor_wrapper_),
            base::MakeUnique<syncer::SyncErrorFactoryMock>());

    // bad will fail to send changes.
    good->Set(DEFAULTS, "foo", fooValue);
    sync_processor_->set_fail_all_requests(true);
    bad->Set(DEFAULTS, "foo", fooValue);
    sync_processor_->set_fail_all_requests(false);

    EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
              sync_processor_->GetOnlyChange("good", "foo")->change_type());
    EXPECT_EQ(1u, sync_processor_->changes().size());

    // No further changes should be sent from bad.
    sync_processor_->ClearChanges();
    good->Set(DEFAULTS, "foo", barValue);
    bad->Set(DEFAULTS, "foo", barValue);

    EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
              sync_processor_->GetOnlyChange("good", "foo")->change_type());
    EXPECT_EQ(1u, sync_processor_->changes().size());

    // Changes from sync will be sent to good, not to bad.
    {
      syncer::SyncChangeList change_list;
      change_list.push_back(
          settings_sync_util::CreateAdd("good", "bar", barValue, model_type));
      change_list.push_back(
          settings_sync_util::CreateAdd("bad", "bar", barValue, model_type));
      GetSyncableService(model_type)
          ->ProcessSyncChanges(FROM_HERE, change_list);
    }

    {
      base::DictionaryValue dict;
      dict.Set("foo", barValue.CreateDeepCopy());
      dict.Set("bar", barValue.CreateDeepCopy());
      EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
    }
    {
      base::DictionaryValue dict;
      dict.Set("foo", barValue.CreateDeepCopy());
      EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
    }

    // Restarting sync makes everything work again.
    sync_processor_->ClearChanges();
    GetSyncableService(model_type)->StopSyncing(model_type);
    sync_processor_wrapper_.reset(
        new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get()));
    GetSyncableService(model_type)
        ->MergeDataAndStartSyncing(
            model_type, syncer::SyncDataList(),
            std::move(sync_processor_wrapper_),
            base::MakeUnique<syncer::SyncErrorFactoryMock>());

    EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
              sync_processor_->GetOnlyChange("good", "foo")->change_type());
    EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
              sync_processor_->GetOnlyChange("good", "bar")->change_type());
    EXPECT_EQ(syncer::SyncChange::ACTION_ADD,
              sync_processor_->GetOnlyChange("bad", "foo")->change_type());
    EXPECT_EQ(3u, sync_processor_->changes().size());

    sync_processor_->ClearChanges();
    good->Set(DEFAULTS, "foo", fooValue);
    bad->Set(DEFAULTS, "foo", fooValue);

    EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
              sync_processor_->GetOnlyChange("good", "foo")->change_type());
    EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE,
              sync_processor_->GetOnlyChange("good", "foo")->change_type());
    EXPECT_EQ(2u, sync_processor_->changes().size());
  });
}

TEST_F(ExtensionSettingsSyncTest,
       LargeOutgoingChangeRejectedButIncomingAccepted) {
  syncer::ModelType model_type = syncer::APP_SETTINGS;
  Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;

  // This value should be larger than the limit in sync_storage_backend.cc.
  std::string string_10k;
  for (size_t i = 0; i < 10000; ++i) {
    string_10k.append("a");
  }
  base::Value large_value(string_10k);

  PostOnBackendSequenceAndWait(FROM_HERE, [&, this]() {
    GetSyncableService(model_type)
        ->MergeDataAndStartSyncing(
            model_type, syncer::SyncDataList(),
            std::move(sync_processor_wrapper_),
            base::MakeUnique<syncer::SyncErrorFactoryMock>());
  });

  // Large local change rejected and doesn't get sent out.
  ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);

  PostOnBackendSequenceAndWait(FROM_HERE, [&, this]() {
    EXPECT_FALSE(
        storage1->Set(DEFAULTS, "large_value", large_value)->status().ok());
    EXPECT_EQ(0u, sync_processor_->changes().size());
  });

  // Large incoming change should still get accepted.
  ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);

  PostOnBackendSequenceAndWait(FROM_HERE, [&, this]() {
    {
      syncer::SyncChangeList change_list;
      change_list.push_back(settings_sync_util::CreateAdd(
          "s1", "large_value", large_value, model_type));
      change_list.push_back(settings_sync_util::CreateAdd(
          "s2", "large_value", large_value, model_type));
      GetSyncableService(model_type)
          ->ProcessSyncChanges(FROM_HERE, change_list);
    }
    {
      base::DictionaryValue expected;
      expected.Set("large_value", large_value.CreateDeepCopy());
      EXPECT_PRED_FORMAT2(SettingsEq, expected, storage1->Get());
      EXPECT_PRED_FORMAT2(SettingsEq, expected, storage2->Get());
    }

    GetSyncableService(model_type)->StopSyncing(model_type);
  });
}

TEST_F(ExtensionSettingsSyncTest, Dots) {
  syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
  Manifest::Type type = Manifest::TYPE_EXTENSION;

  ValueStore* storage = AddExtensionAndGetStorage("ext", type);

  PostOnBackendSequenceAndWait(FROM_HERE, [&, this]() {
    {
      syncer::SyncDataList sync_data_list;
      std::unique_ptr<base::Value> string_value(new base::Value("value"));
      sync_data_list.push_back(settings_sync_util::CreateData(
          "ext", "key.with.dot", *string_value, model_type));

      GetSyncableService(model_type)
          ->MergeDataAndStartSyncing(
              model_type, sync_data_list, std::move(sync_processor_wrapper_),
              base::MakeUnique<syncer::SyncErrorFactoryMock>());
    }

    // Test dots in keys that come from sync.
    {
      ValueStore::ReadResult data = storage->Get();
      ASSERT_TRUE(data->status().ok());

      base::DictionaryValue expected_data;
      expected_data.SetWithoutPathExpansion(
          "key.with.dot", base::MakeUnique<base::Value>("value"));
      EXPECT_EQ(expected_data, data->settings());
    }

    // Test dots in keys going to sync.
    {
      std::unique_ptr<base::Value> string_value(new base::Value("spot"));
      storage->Set(DEFAULTS, "key.with.spot", *string_value);

      ASSERT_EQ(1u, sync_processor_->changes().size());
      SettingSyncData* sync_data = sync_processor_->changes()[0].get();
      EXPECT_EQ(syncer::SyncChange::ACTION_ADD, sync_data->change_type());
      EXPECT_EQ("ext", sync_data->extension_id());
      EXPECT_EQ("key.with.spot", sync_data->key());
      EXPECT_TRUE(sync_data->value().Equals(string_value.get()));
    }
  });
}

// In other (frontend) tests, we assume that the result of GetStorage
// is a pointer to the a Storage owned by a Frontend object, but for
// the unlimitedStorage case, this might not be true. So, write the
// tests in a "callback" style.  We should really rewrite all tests to
// be asynchronous in this way.

namespace {

static void UnlimitedSyncStorageTestCallback(ValueStore* sync_storage) {
  // Sync storage should still run out after ~100K; the unlimitedStorage
  // permission can't apply to sync.
  std::unique_ptr<base::Value> kilobyte = util::CreateKilobyte();
  for (int i = 0; i < 100; ++i) {
    sync_storage->Set(ValueStore::DEFAULTS, base::IntToString(i), *kilobyte);
  }

  EXPECT_FALSE(sync_storage->Set(ValueStore::DEFAULTS, "WillError", *kilobyte)
                  ->status().ok());
}

static void UnlimitedLocalStorageTestCallback(ValueStore* local_storage) {
  // Local storage should never run out.
  std::unique_ptr<base::Value> megabyte = util::CreateMegabyte();
  for (int i = 0; i < 7; ++i) {
    local_storage->Set(ValueStore::DEFAULTS, base::IntToString(i), *megabyte);
  }

  EXPECT_TRUE(local_storage->Set(ValueStore::DEFAULTS, "WontError", *megabyte)
                   ->status().ok());
}

}  // namespace

#if defined(OS_WIN)
// See: http://crbug.com/227296
#define MAYBE_UnlimitedStorageForLocalButNotSync \
  DISABLED_UnlimitedStorageForLocalButNotSync
#else
#define MAYBE_UnlimitedStorageForLocalButNotSync \
  UnlimitedStorageForLocalButNotSync
#endif
TEST_F(ExtensionSettingsSyncTest, MAYBE_UnlimitedStorageForLocalButNotSync) {
  const std::string id = "ext";
  std::set<std::string> permissions;
  permissions.insert("unlimitedStorage");
  scoped_refptr<const Extension> extension =
      util::AddExtensionWithIdAndPermissions(
          profile_.get(), id, Manifest::TYPE_EXTENSION, permissions);

  frontend_->RunWithStorage(extension,
                            settings_namespace::SYNC,
                            base::Bind(&UnlimitedSyncStorageTestCallback));
  frontend_->RunWithStorage(extension,
                            settings_namespace::LOCAL,
                            base::Bind(&UnlimitedLocalStorageTestCallback));

  content::RunAllTasksUntilIdle();
}

}  // namespace extensions
