// Copyright 2013 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 "components/policy/core/common/configuration_policy_provider_test.h"

#include <utility>

#include "base/bind.h"
#include "base/callback.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/values.h"
#include "components/policy/core/common/configuration_policy_provider.h"
#include "components/policy/core/common/external_data_fetcher.h"
#include "components/policy/core/common/mock_configuration_policy_provider.h"
#include "components/policy/core/common/policy_bundle.h"
#include "components/policy/core/common/policy_map.h"
#include "components/policy/core/common/policy_namespace.h"
#include "components/policy/core/common/policy_test_utils.h"
#include "components/policy/core/common/policy_types.h"
#include "testing/gmock/include/gmock/gmock.h"

using ::testing::Mock;
using ::testing::_;

namespace {

const char kTestChromeSchema[] =
    "{"
    "  \"type\": \"object\","
    "  \"properties\": {"
    "    \"StringPolicy\": { \"type\": \"string\" },"
    "    \"BooleanPolicy\": { \"type\": \"boolean\" },"
    "    \"IntegerPolicy\": { \"type\": \"integer\" },"
    "    \"StringListPolicy\": {"
    "      \"type\": \"array\","
    "      \"items\": { \"type\": \"string\" }"
    "    },"
    "    \"DictionaryPolicy\": {"
    "      \"type\": \"object\","
    "      \"properties\": {"
    "        \"bool\": { \"type\": \"boolean\" },"
    "        \"double\": { \"type\": \"number\" },"
    "        \"int\": { \"type\": \"integer\" },"
    "        \"string\": { \"type\": \"string\" },"
    "        \"array\": {"
    "          \"type\": \"array\","
    "          \"items\": { \"type\": \"string\" }"
    "        },"
    "        \"dictionary\": {"
    "          \"type\": \"object\","
    "          \"properties\": {"
    "            \"sub\": { \"type\": \"string\" },"
    "            \"sublist\": {"
    "              \"type\": \"array\","
    "              \"items\": {"
    "                \"type\": \"object\","
    "                \"properties\": {"
    "                  \"aaa\": { \"type\": \"integer\" },"
    "                  \"bbb\": { \"type\": \"integer\" },"
    "                  \"ccc\": { \"type\": \"string\" },"
    "                  \"ddd\": { \"type\": \"string\" }"
    "                }"
    "              }"
    "            }"
    "          }"
    "        },"
    "        \"list\": {"
    "          \"type\": \"array\","
    "          \"items\": {"
    "            \"type\": \"object\","
    "            \"properties\": {"
    "              \"subdictindex\": { \"type\": \"integer\" },"
    "              \"subdict\": {"
    "                \"type\": \"object\","
    "                \"properties\": {"
    "                  \"bool\": { \"type\": \"boolean\" },"
    "                  \"double\": { \"type\": \"number\" },"
    "                  \"int\": { \"type\": \"integer\" },"
    "                  \"string\": { \"type\": \"string\" }"
    "                }"
    "              }"
    "            }"
    "          }"
    "        },"
    "        \"dict\": {"
    "          \"type\": \"object\","
    "          \"properties\": {"
    "            \"bool\": { \"type\": \"boolean\" },"
    "            \"double\": { \"type\": \"number\" },"
    "            \"int\": { \"type\": \"integer\" },"
    "            \"string\": { \"type\": \"string\" },"
    "            \"list\": {"
    "              \"type\": \"array\","
    "              \"items\": {"
    "                \"type\": \"object\","
    "                \"properties\": {"
    "                  \"subdictindex\": { \"type\": \"integer\" },"
    "                  \"subdict\": {"
    "                    \"type\": \"object\","
    "                    \"properties\": {"
    "                      \"bool\": { \"type\": \"boolean\" },"
    "                      \"double\": { \"type\": \"number\" },"
    "                      \"int\": { \"type\": \"integer\" },"
    "                      \"string\": { \"type\": \"string\" }"
    "                    }"
    "                  }"
    "                }"
    "              }"
    "            }"
    "          }"
    "        }"
    "      }"
    "    }"
    "  }"
    "}";

}  // anonymous namespace

namespace policy {

namespace test_keys {

// These are the defaults for PolicyProviderTestHarness but they are generally
// available for use in other tests.  Subclasses of PolicyProviderTestHarness
// may use different values.
const char kKeyString[] = "StringPolicy";
const char kKeyBoolean[] = "BooleanPolicy";
const char kKeyInteger[] = "IntegerPolicy";
const char kKeyStringList[] = "StringListPolicy";
const char kKeyDictionary[] = "DictionaryPolicy";

}  // namespace test_keys

PolicyTestBase::PolicyTestBase() {}

PolicyTestBase::~PolicyTestBase() {}

void PolicyTestBase::SetUp() {
  const PolicyNamespace ns(POLICY_DOMAIN_CHROME, "");
  ASSERT_TRUE(RegisterSchema(ns, kTestChromeSchema));
}

void PolicyTestBase::TearDown() {
  base::RunLoop().RunUntilIdle();
}

bool PolicyTestBase::RegisterSchema(const PolicyNamespace& ns,
                                    const std::string& schema_string) {
  std::string error;
  Schema schema = Schema::Parse(schema_string, &error);
  if (schema.valid()) {
    schema_registry_.RegisterComponent(ns, schema);
    return true;
  }
  ADD_FAILURE() << error;
  return false;
}

PolicyProviderTestHarness::PolicyProviderTestHarness(PolicyLevel level,
                                                     PolicyScope scope,
                                                     PolicySource source)
    : key_string_(test_keys::kKeyString),
      key_boolean_(test_keys::kKeyBoolean),
      key_integer_(test_keys::kKeyInteger),
      key_stringlist_(test_keys::kKeyStringList),
      key_dictionary_(test_keys::kKeyDictionary),
      test_schema_(kTestChromeSchema),
      level_(level),
      scope_(scope),
      source_(source) {
}

PolicyProviderTestHarness::~PolicyProviderTestHarness() {}

void PolicyProviderTestHarness::Install3rdPartyPolicy(
    const base::DictionaryValue* policies) {
  FAIL();
}

ConfigurationPolicyProviderTest::ConfigurationPolicyProviderTest() {}

ConfigurationPolicyProviderTest::~ConfigurationPolicyProviderTest() {}

void ConfigurationPolicyProviderTest::SetUp() {
  harness_.reset((*GetParam())());
  harness_->SetUp();

  const PolicyNamespace chrome_ns(POLICY_DOMAIN_CHROME, "");
  ASSERT_TRUE(RegisterSchema(chrome_ns, harness_->test_schema()));

  Schema chrome_schema = *schema_registry_.schema_map()->GetSchema(chrome_ns);
  Schema extension_schema =
      chrome_schema.GetKnownProperty(harness_->key_dictionary());
  ASSERT_TRUE(extension_schema.valid());
  schema_registry_.RegisterComponent(
      PolicyNamespace(POLICY_DOMAIN_EXTENSIONS,
                      "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
      extension_schema);
  schema_registry_.RegisterComponent(
      PolicyNamespace(POLICY_DOMAIN_EXTENSIONS,
                      "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"),
      extension_schema);
  schema_registry_.RegisterComponent(
      PolicyNamespace(POLICY_DOMAIN_EXTENSIONS,
                      "cccccccccccccccccccccccccccccccc"),
      extension_schema);

  provider_.reset(
      harness_->CreateProvider(&schema_registry_, loop_.task_runner()));
  provider_->Init(&schema_registry_);
  // Some providers do a reload on init. Make sure any notifications generated
  // are fired now.
  base::RunLoop().RunUntilIdle();

  const PolicyBundle kEmptyBundle;
  EXPECT_TRUE(provider_->policies().Equals(kEmptyBundle));
}

void ConfigurationPolicyProviderTest::TearDown() {
  // Give providers the chance to clean up after themselves on the file thread.
  if (provider_) {
    provider_->Shutdown();
    provider_.reset();
  }

  PolicyTestBase::TearDown();
}

void ConfigurationPolicyProviderTest::CheckValue(
    const char* policy_name,
    const base::Value& expected_value,
    base::Closure install_value) {
  // Install the value, reload policy and check the provider for the value.
  install_value.Run();
  provider_->RefreshPolicies();
  base::RunLoop().RunUntilIdle();
  PolicyBundle expected_bundle;
  expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
      .Set(policy_name, harness_->policy_level(), harness_->policy_scope(),
           harness_->policy_source(), expected_value.CreateDeepCopy(), nullptr);
  bool match = provider_->policies().Equals(expected_bundle);
  if (!match) {
    LOG(ERROR) << "EXPECTED: " << expected_bundle;
    LOG(ERROR) << "ACTUAL: " << provider_->policies();
  }
  EXPECT_TRUE(match);
  // TODO(joaodasilva): set the policy in the POLICY_DOMAIN_EXTENSIONS too,
  // and extend the |expected_bundle|, once all providers are ready.
}

TEST_P(ConfigurationPolicyProviderTest, Empty) {
  provider_->RefreshPolicies();
  base::RunLoop().RunUntilIdle();
  const PolicyBundle kEmptyBundle;
  EXPECT_TRUE(provider_->policies().Equals(kEmptyBundle));
}

TEST_P(ConfigurationPolicyProviderTest, StringValue) {
  const char kTestString[] = "string_value";
  base::StringValue expected_value(kTestString);
  CheckValue(harness_->key_string(),
             expected_value,
             base::Bind(&PolicyProviderTestHarness::InstallStringPolicy,
                        base::Unretained(harness_.get()),
                        harness_->key_string(),
                        kTestString));
}

TEST_P(ConfigurationPolicyProviderTest, BooleanValue) {
  base::FundamentalValue expected_value(true);
  CheckValue(harness_->key_boolean(),
             expected_value,
             base::Bind(&PolicyProviderTestHarness::InstallBooleanPolicy,
                        base::Unretained(harness_.get()),
                        harness_->key_boolean(),
                        true));
}

TEST_P(ConfigurationPolicyProviderTest, IntegerValue) {
  base::FundamentalValue expected_value(42);
  CheckValue(harness_->key_integer(),
             expected_value,
             base::Bind(&PolicyProviderTestHarness::InstallIntegerPolicy,
                        base::Unretained(harness_.get()),
                        harness_->key_integer(),
                        42));
}

TEST_P(ConfigurationPolicyProviderTest, StringListValue) {
  base::ListValue expected_value;
  expected_value.Set(0U, new base::StringValue("first"));
  expected_value.Set(1U, new base::StringValue("second"));
  CheckValue(harness_->key_stringlist(),
             expected_value,
             base::Bind(&PolicyProviderTestHarness::InstallStringListPolicy,
                        base::Unretained(harness_.get()),
                        harness_->key_stringlist(),
                        &expected_value));
}

TEST_P(ConfigurationPolicyProviderTest, DictionaryValue) {
  base::DictionaryValue expected_value;
  expected_value.SetBoolean("bool", true);
  expected_value.SetDouble("double", 123.456);
  expected_value.SetInteger("int", 123);
  expected_value.SetString("string", "omg");

  base::ListValue* list = new base::ListValue();
  list->Set(0U, new base::StringValue("first"));
  list->Set(1U, new base::StringValue("second"));
  expected_value.Set("array", list);

  base::DictionaryValue* dict = new base::DictionaryValue();
  dict->SetString("sub", "value");
  list = new base::ListValue();
  std::unique_ptr<base::DictionaryValue> sub(new base::DictionaryValue());
  sub->SetInteger("aaa", 111);
  sub->SetInteger("bbb", 222);
  list->Append(std::move(sub));
  sub.reset(new base::DictionaryValue());
  sub->SetString("ccc", "333");
  sub->SetString("ddd", "444");
  list->Append(std::move(sub));
  dict->Set("sublist", list);
  expected_value.Set("dictionary", dict);

  CheckValue(harness_->key_dictionary(),
             expected_value,
             base::Bind(&PolicyProviderTestHarness::InstallDictionaryPolicy,
                        base::Unretained(harness_.get()),
                        harness_->key_dictionary(),
                        &expected_value));
}

TEST_P(ConfigurationPolicyProviderTest, RefreshPolicies) {
  PolicyBundle bundle;
  EXPECT_TRUE(provider_->policies().Equals(bundle));

  // OnUpdatePolicy is called even when there are no changes.
  MockConfigurationPolicyObserver observer;
  provider_->AddObserver(&observer);
  EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(1);
  provider_->RefreshPolicies();
  base::RunLoop().RunUntilIdle();
  Mock::VerifyAndClearExpectations(&observer);

  EXPECT_TRUE(provider_->policies().Equals(bundle));

  // OnUpdatePolicy is called when there are changes.
  harness_->InstallStringPolicy(harness_->key_string(), "value");
  EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(1);
  provider_->RefreshPolicies();
  base::RunLoop().RunUntilIdle();
  Mock::VerifyAndClearExpectations(&observer);

  bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
      .Set(harness_->key_string(), harness_->policy_level(),
           harness_->policy_scope(), harness_->policy_source(),
           base::WrapUnique(new base::StringValue("value")), nullptr);
  EXPECT_TRUE(provider_->policies().Equals(bundle));
  provider_->RemoveObserver(&observer);
}

Configuration3rdPartyPolicyProviderTest::
    Configuration3rdPartyPolicyProviderTest() {}

Configuration3rdPartyPolicyProviderTest::
    ~Configuration3rdPartyPolicyProviderTest() {}

TEST_P(Configuration3rdPartyPolicyProviderTest, Load3rdParty) {
  base::DictionaryValue policy_dict;
  policy_dict.SetBoolean("bool", true);
  policy_dict.SetDouble("double", 123.456);
  policy_dict.SetInteger("int", 789);
  policy_dict.SetString("string", "string value");

  base::ListValue* list = new base::ListValue();
  for (int i = 0; i < 2; ++i) {
    std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
    dict->SetInteger("subdictindex", i);
    dict->Set("subdict", policy_dict.DeepCopy());
    list->Append(std::move(dict));
  }
  policy_dict.Set("list", list);
  policy_dict.Set("dict", policy_dict.DeepCopy());

  // Install these policies as a Chrome policy.
  harness_->InstallDictionaryPolicy(harness_->key_dictionary(), &policy_dict);
  // Install them as 3rd party policies too.
  base::DictionaryValue policy_3rdparty;
  policy_3rdparty.Set("extensions.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                      policy_dict.DeepCopy());
  policy_3rdparty.Set("extensions.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
                      policy_dict.DeepCopy());
  // Install invalid 3rd party policies that shouldn't be loaded. These also
  // help detecting memory leaks in the code paths that detect invalid input.
  policy_3rdparty.Set("invalid-domain.component", policy_dict.DeepCopy());
  policy_3rdparty.Set("extensions.cccccccccccccccccccccccccccccccc",
                      new base::StringValue("invalid-value"));
  harness_->Install3rdPartyPolicy(&policy_3rdparty);

  provider_->RefreshPolicies();
  base::RunLoop().RunUntilIdle();

  PolicyMap expected_policy;
  expected_policy.Set(harness_->key_dictionary(), harness_->policy_level(),
                      harness_->policy_scope(), harness_->policy_source(),
                      policy_dict.CreateDeepCopy(), nullptr);
  PolicyBundle expected_bundle;
  expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
      .CopyFrom(expected_policy);
  expected_policy.Clear();
  expected_policy.LoadFrom(&policy_dict,
                           harness_->policy_level(),
                           harness_->policy_scope(),
                           harness_->policy_source());
  expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS,
                                      "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"))
      .CopyFrom(expected_policy);
  expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS,
                                      "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"))
      .CopyFrom(expected_policy);
  EXPECT_TRUE(provider_->policies().Equals(expected_bundle));
}

}  // namespace policy
