<commit_before>// 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 "base/bind.h"
#include "base/json/json_writer.h"
#include "chrome/browser/extensions/api/storage/settings_frontend.h"
#include "chrome/browser/extensions/api/storage/settings_namespace.h"
#include "chrome/browser/extensions/api/storage/settings_sync_util.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_test_message_listener.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/extensions/value_builder.h"
#include "chrome/test/base/ui_test_utils.h"
#include "sync/api/sync_change.h"
#include "sync/api/sync_change_processor.h"
#include "sync/api/sync_error_factory.h"
#include "sync/api/sync_error_factory_mock.h"
#include "testing/gmock/include/gmock/gmock.h"

#if defined(ENABLE_CONFIGURATION_POLICY)
#include "chrome/browser/policy/browser_policy_connector.h"
#include "chrome/browser/policy/mock_configuration_policy_provider.h"
#include "chrome/browser/policy/policy_bundle.h"
#include "chrome/browser/policy/policy_map.h"
#endif

namespace extensions {

using settings_namespace::FromString;
using settings_namespace::LOCAL;
using settings_namespace::MANAGED;
using settings_namespace::Namespace;
using settings_namespace::SYNC;
using settings_namespace::ToString;
using testing::AnyNumber;
using testing::Return;
using testing::_;

namespace {

// TODO(kalman): test both EXTENSION_SETTINGS and APP_SETTINGS.
const syncer::ModelType kModelType = syncer::EXTENSION_SETTINGS;

// The managed_storage extension has a key defined in its manifest, so that
// its extension ID is well-known and the policy system can push policies for
// the extension.
const char kManagedStorageExtensionId[] = "kjmkgkdkpedkejedfhmfcenooemhbpbo";

class NoopSyncChangeProcessor : public syncer::SyncChangeProcessor {
 public:
  virtual syncer::SyncError ProcessSyncChanges(
      const tracked_objects::Location& from_here,
      const syncer::SyncChangeList& change_list) OVERRIDE {
    return syncer::SyncError();
  }

  virtual ~NoopSyncChangeProcessor() {};
};

class SyncChangeProcessorDelegate : public syncer::SyncChangeProcessor {
 public:
  explicit SyncChangeProcessorDelegate(syncer::SyncChangeProcessor* recipient)
      : recipient_(recipient) {
    DCHECK(recipient_);
  }
  virtual ~SyncChangeProcessorDelegate() {}

  // syncer::SyncChangeProcessor implementation.
  virtual syncer::SyncError ProcessSyncChanges(
      const tracked_objects::Location& from_here,
      const syncer::SyncChangeList& change_list) OVERRIDE {
    return recipient_->ProcessSyncChanges(from_here, change_list);
  }

 private:
  // The recipient of all sync changes.
  syncer::SyncChangeProcessor* recipient_;

  DISALLOW_COPY_AND_ASSIGN(SyncChangeProcessorDelegate);
};

}  // namespace

class ExtensionSettingsApiTest : public ExtensionApiTest {
 protected:
  virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
    ExtensionApiTest::SetUpInProcessBrowserTestFixture();

#if defined(ENABLE_CONFIGURATION_POLICY)
    EXPECT_CALL(policy_provider_, IsInitializationComplete(_))
        .WillRepeatedly(Return(true));
    EXPECT_CALL(policy_provider_, RegisterPolicyDomain(_)).Times(AnyNumber());
    policy::BrowserPolicyConnector::SetPolicyProviderForTesting(
        &policy_provider_);
#endif
  }

  void ReplyWhenSatisfied(
      Namespace settings_namespace,
      const std::string& normal_action,
      const std::string& incognito_action) {
    MaybeLoadAndReplyWhenSatisfied(
        settings_namespace, normal_action, incognito_action, NULL, false);
  }

  const Extension* LoadAndReplyWhenSatisfied(
      Namespace settings_namespace,
      const std::string& normal_action,
      const std::string& incognito_action,
      const std::string& extension_dir) {
    return MaybeLoadAndReplyWhenSatisfied(
        settings_namespace,
        normal_action,
        incognito_action,
        &extension_dir,
        false);
  }

  void FinalReplyWhenSatisfied(
      Namespace settings_namespace,
      const std::string& normal_action,
      const std::string& incognito_action) {
    MaybeLoadAndReplyWhenSatisfied(
        settings_namespace, normal_action, incognito_action, NULL, true);
  }

  void InitSync(syncer::SyncChangeProcessor* sync_processor) {
    base::MessageLoop::current()->RunUntilIdle();
    InitSyncWithSyncableService(
        sync_processor,
        browser()->profile()->GetExtensionService()->settings_frontend()->
              GetBackendForSync(kModelType));
  }

  void SendChanges(const syncer::SyncChangeList& change_list) {
    base::MessageLoop::current()->RunUntilIdle();
    SendChangesToSyncableService(
        change_list,
        browser()->profile()->GetExtensionService()->settings_frontend()->
              GetBackendForSync(kModelType));
  }

#if defined(ENABLE_CONFIGURATION_POLICY)
  void SetPolicies(const base::DictionaryValue& policies) {
    scoped_ptr<policy::PolicyBundle> bundle(new policy::PolicyBundle());
    policy::PolicyMap& policy_map = bundle->Get(policy::PolicyNamespace(
        policy::POLICY_DOMAIN_EXTENSIONS, kManagedStorageExtensionId));
    policy_map.LoadFrom(
        &policies, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER);
    policy_provider_.UpdatePolicy(bundle.Pass());
  }
#endif

 private:
  const Extension* MaybeLoadAndReplyWhenSatisfied(
      Namespace settings_namespace,
      const std::string& normal_action,
      const std::string& incognito_action,
      // May be NULL to imply not loading the extension.
      const std::string* extension_dir,
      bool is_final_action) {
    ExtensionTestMessageListener listener("waiting", true);
    ExtensionTestMessageListener listener_incognito("waiting_incognito", true);

    // Only load the extension after the listeners have been set up, to avoid
    // initialisation race conditions.
    const Extension* extension = NULL;
    if (extension_dir) {
      extension = LoadExtensionIncognito(
          test_data_dir_.AppendASCII("settings").AppendASCII(*extension_dir));
      EXPECT_TRUE(extension);
    }

    EXPECT_TRUE(listener.WaitUntilSatisfied());
    EXPECT_TRUE(listener_incognito.WaitUntilSatisfied());

    listener.Reply(
        CreateMessage(settings_namespace, normal_action, is_final_action));
    listener_incognito.Reply(
        CreateMessage(settings_namespace, incognito_action, is_final_action));
    return extension;
  }

  std::string CreateMessage(
      Namespace settings_namespace,
      const std::string& action,
      bool is_final_action) {
    scoped_ptr<DictionaryValue> message(new DictionaryValue());
    message->SetString("namespace", ToString(settings_namespace));
    message->SetString("action", action);
    message->SetBoolean("isFinalAction", is_final_action);
    std::string message_json;
    base::JSONWriter::Write(message.get(), &message_json);
    return message_json;
  }

  void InitSyncWithSyncableService(
      syncer::SyncChangeProcessor* sync_processor,
      syncer::SyncableService* settings_service) {
    EXPECT_FALSE(settings_service->MergeDataAndStartSyncing(
        kModelType,
        syncer::SyncDataList(),
        scoped_ptr<syncer::SyncChangeProcessor>(
            new SyncChangeProcessorDelegate(sync_processor)),
        scoped_ptr<syncer::SyncErrorFactory>(
            new syncer::SyncErrorFactoryMock())).error().IsSet());
  }

  void SendChangesToSyncableService(
      const syncer::SyncChangeList& change_list,
      syncer::SyncableService* settings_service) {
    EXPECT_FALSE(
        settings_service->ProcessSyncChanges(FROM_HERE, change_list).IsSet());
  }

 protected:
#if defined(ENABLE_CONFIGURATION_POLICY)
  policy::MockConfigurationPolicyProvider policy_provider_;
#endif
};

IN_PROC_BROWSER_TEST_F(ExtensionSettingsApiTest, SimpleTest) {
  ASSERT_TRUE(RunExtensionTest("settings/simple_test")) << message_;
}

// Structure of this test taken from IncognitoSplitMode.
// Note that only split-mode incognito is tested, because spanning mode
// incognito looks the same as normal mode when the only API activity comes
// from background pages.
IN_PROC_BROWSER_TEST_F(ExtensionSettingsApiTest, SplitModeIncognito) {
  // We need 2 ResultCatchers because we'll be running the same test in both
  // regular and incognito mode.
  ResultCatcher catcher, catcher_incognito;
  catcher.RestrictToProfile(browser()->profile());
  catcher_incognito.RestrictToProfile(
      browser()->profile()->GetOffTheRecordProfile());

  LoadAndReplyWhenSatisfied(SYNC,
      "assertEmpty", "assertEmpty", "split_incognito");
  ReplyWhenSatisfied(SYNC, "noop", "setFoo");
  ReplyWhenSatisfied(SYNC, "assertFoo", "assertFoo");
  ReplyWhenSatisfied(SYNC, "clear", "noop");
  ReplyWhenSatisfied(SYNC, "assertEmpty", "assertEmpty");
  ReplyWhenSatisfied(SYNC, "setFoo", "noop");
  ReplyWhenSatisfied(SYNC, "assertFoo", "assertFoo");<commit_msg>Disable ExtensionSettingsApiTest.SimpleTest on win aura<commit_after>// 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 "base/bind.h"
#include "base/json/json_writer.h"
#include "chrome/browser/extensions/api/storage/settings_frontend.h"
#include "chrome/browser/extensions/api/storage/settings_namespace.h"
#include "chrome/browser/extensions/api/storage/settings_sync_util.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_test_message_listener.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/extensions/value_builder.h"
#include "chrome/test/base/ui_test_utils.h"
#include "sync/api/sync_change.h"
#include "sync/api/sync_change_processor.h"
#include "sync/api/sync_error_factory.h"
#include "sync/api/sync_error_factory_mock.h"
#include "testing/gmock/include/gmock/gmock.h"

#if defined(ENABLE_CONFIGURATION_POLICY)
#include "chrome/browser/policy/browser_policy_connector.h"
#include "chrome/browser/policy/mock_configuration_policy_provider.h"
#include "chrome/browser/policy/policy_bundle.h"
#include "chrome/browser/policy/policy_map.h"
#endif

namespace extensions {

using settings_namespace::FromString;
using settings_namespace::LOCAL;
using settings_namespace::MANAGED;
using settings_namespace::Namespace;
using settings_namespace::SYNC;
using settings_namespace::ToString;
using testing::AnyNumber;
using testing::Return;
using testing::_;

namespace {

// TODO(kalman): test both EXTENSION_SETTINGS and APP_SETTINGS.
const syncer::ModelType kModelType = syncer::EXTENSION_SETTINGS;

// The managed_storage extension has a key defined in its manifest, so that
// its extension ID is well-known and the policy system can push policies for
// the extension.
const char kManagedStorageExtensionId[] = "kjmkgkdkpedkejedfhmfcenooemhbpbo";

class NoopSyncChangeProcessor : public syncer::SyncChangeProcessor {
 public:
  virtual syncer::SyncError ProcessSyncChanges(
      const tracked_objects::Location& from_here,
      const syncer::SyncChangeList& change_list) OVERRIDE {
    return syncer::SyncError();
  }

  virtual ~NoopSyncChangeProcessor() {};
};

class SyncChangeProcessorDelegate : public syncer::SyncChangeProcessor {
 public:
  explicit SyncChangeProcessorDelegate(syncer::SyncChangeProcessor* recipient)
      : recipient_(recipient) {
    DCHECK(recipient_);
  }
  virtual ~SyncChangeProcessorDelegate() {}

  // syncer::SyncChangeProcessor implementation.
  virtual syncer::SyncError ProcessSyncChanges(
      const tracked_objects::Location& from_here,
      const syncer::SyncChangeList& change_list) OVERRIDE {
    return recipient_->ProcessSyncChanges(from_here, change_list);
  }

 private:
  // The recipient of all sync changes.
  syncer::SyncChangeProcessor* recipient_;

  DISALLOW_COPY_AND_ASSIGN(SyncChangeProcessorDelegate);
};

}  // namespace

class ExtensionSettingsApiTest : public ExtensionApiTest {
 protected:
  virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
    ExtensionApiTest::SetUpInProcessBrowserTestFixture();

#if defined(ENABLE_CONFIGURATION_POLICY)
    EXPECT_CALL(policy_provider_, IsInitializationComplete(_))
        .WillRepeatedly(Return(true));
    EXPECT_CALL(policy_provider_, RegisterPolicyDomain(_)).Times(AnyNumber());
    policy::BrowserPolicyConnector::SetPolicyProviderForTesting(
        &policy_provider_);
#endif
  }

  void ReplyWhenSatisfied(
      Namespace settings_namespace,
      const std::string& normal_action,
      const std::string& incognito_action) {
    MaybeLoadAndReplyWhenSatisfied(
        settings_namespace, normal_action, incognito_action, NULL, false);
  }

  const Extension* LoadAndReplyWhenSatisfied(
      Namespace settings_namespace,
      const std::string& normal_action,
      const std::string& incognito_action,
      const std::string& extension_dir) {
    return MaybeLoadAndReplyWhenSatisfied(
        settings_namespace,
        normal_action,
        incognito_action,
        &extension_dir,
        false);
  }

  void FinalReplyWhenSatisfied(
      Namespace settings_namespace,
      const std::string& normal_action,
      const std::string& incognito_action) {
    MaybeLoadAndReplyWhenSatisfied(
        settings_namespace, normal_action, incognito_action, NULL, true);
  }

  void InitSync(syncer::SyncChangeProcessor* sync_processor) {
    base::MessageLoop::current()->RunUntilIdle();
    InitSyncWithSyncableService(
        sync_processor,
        browser()->profile()->GetExtensionService()->settings_frontend()->
              GetBackendForSync(kModelType));
  }

  void SendChanges(const syncer::SyncChangeList& change_list) {
    base::MessageLoop::current()->RunUntilIdle();
    SendChangesToSyncableService(
        change_list,
        browser()->profile()->GetExtensionService()->settings_frontend()->
              GetBackendForSync(kModelType));
  }

#if defined(ENABLE_CONFIGURATION_POLICY)
  void SetPolicies(const base::DictionaryValue& policies) {
    scoped_ptr<policy::PolicyBundle> bundle(new policy::PolicyBundle());
    policy::PolicyMap& policy_map = bundle->Get(policy::PolicyNamespace(
        policy::POLICY_DOMAIN_EXTENSIONS, kManagedStorageExtensionId));
    policy_map.LoadFrom(
        &policies, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER);
    policy_provider_.UpdatePolicy(bundle.Pass());
  }
#endif

 private:
  const Extension* MaybeLoadAndReplyWhenSatisfied(
      Namespace settings_namespace,
      const std::string& normal_action,
      const std::string& incognito_action,
      // May be NULL to imply not loading the extension.
      const std::string* extension_dir,
      bool is_final_action) {
    ExtensionTestMessageListener listener("waiting", true);
    ExtensionTestMessageListener listener_incognito("waiting_incognito", true);

    // Only load the extension after the listeners have been set up, to avoid
    // initialisation race conditions.
    const Extension* extension = NULL;
    if (extension_dir) {
      extension = LoadExtensionIncognito(
          test_data_dir_.AppendASCII("settings").AppendASCII(*extension_dir));
      EXPECT_TRUE(extension);
    }

    EXPECT_TRUE(listener.WaitUntilSatisfied());
    EXPECT_TRUE(listener_incognito.WaitUntilSatisfied());

    listener.Reply(
        CreateMessage(settings_namespace, normal_action, is_final_action));
    listener_incognito.Reply(
        CreateMessage(settings_namespace, incognito_action, is_final_action));
    return extension;
  }

  std::string CreateMessage(
      Namespace settings_namespace,
      const std::string& action,
      bool is_final_action) {
    scoped_ptr<DictionaryValue> message(new DictionaryValue());
    message->SetString("namespace", ToString(settings_namespace));
    message->SetString("action", action);
    message->SetBoolean("isFinalAction", is_final_action);
    std::string message_json;
    base::JSONWriter::Write(message.get(), &message_json);
    return message_json;
  }

  void InitSyncWithSyncableService(
      syncer::SyncChangeProcessor* sync_processor,
      syncer::SyncableService* settings_service) {
    EXPECT_FALSE(settings_service->MergeDataAndStartSyncing(
        kModelType,
        syncer::SyncDataList(),
        scoped_ptr<syncer::SyncChangeProcessor>(
            new SyncChangeProcessorDelegate(sync_processor)),
        scoped_ptr<syncer::SyncErrorFactory>(
            new syncer::SyncErrorFactoryMock())).error().IsSet());
  }

  void SendChangesToSyncableService(
      const syncer::SyncChangeList& change_list,
      syncer::SyncableService* settings_service) {
    EXPECT_FALSE(
        settings_service->ProcessSyncChanges(FROM_HERE, change_list).IsSet());
  }

 protected:
#if defined(ENABLE_CONFIGURATION_POLICY)
  policy::MockConfigurationPolicyProvider policy_provider_;
#endif
};

// Flaky on Win Aura bots. http://crbug.com/248032
#if defined(OS_WIN) && defined(USE_AURA)
#define MAYBE_SimpleTest DISABLED_SimpleTest
#else
#define MAYBE_SimpleTest SimpleTest
#endif

IN_PROC_BROWSER_TEST_F(ExtensionSettingsApiTest, MAYBE_SimpleTest) {
  ASSERT_TRUE(RunExtensionTest("settings/simple_test")) << message_;
}

// Structure of this test taken from IncognitoSplitMode.
// Note that only split-mode incognito is tested, because spanning mode
// incognito looks the same as normal mode when the only API activity comes
// from background pages.
IN_PROC_BROWSER_TEST_F(ExtensionSettingsApiTest, SplitModeIncognito) {
  // We need 2 ResultCatchers because we'll be running the same test in both
  // regular and incognito mode.
  ResultCatcher catcher, catcher_incognito;
  catcher.RestrictToProfile(browser()->profile());
  catcher_incognito.RestrictToProfile(
      browser()->profile()->GetOffTheRecordProfile());

  LoadAndReplyWhenSatisfied(SYNC,
      "assertEmpty", "assertEmpty", "split_incognito");
  ReplyWhenSatisfied(SYNC, "noop", "setFoo");
  ReplyWhenSatisfied(SYNC, "assertFoo", "assertFoo");
  ReplyWhenSatisfied(SYNC, "clear", "noop");
  ReplyWhenSatisfied(SYNC, "assertEmpty", "assertEmpty");
  ReplyWhenSatisfied(SYNC, "setFoo", "noop");
  ReplyWhenSatisfied(SYNC, "assertFoo", "assertFoo");
{'fraction_non_alphanumeric': 0.10096856230723446, 'fraction_numerical': 0.0008657540176397381, 'mean_word_length': 5.1750751754092885, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5214215', 'n_tokens_mistral': 5417, 'n_tokens_neox': 5297, 'n_words': 1044}