// Copyright 2015 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 "remoting/host/policy_watcher.h"

#include "base/bind.h"
#include "base/json/json_writer.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/mock_log.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "components/policy/core/common/fake_async_policy_loader.h"
#include "components/policy/policy_constants.h"
#include "remoting/host/dns_blackhole_checker.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace remoting {

namespace key = ::policy::key;

MATCHER_P(IsPolicies, dict, "") {
  bool equal = arg->Equals(dict);
  if (!equal) {
    std::string actual_value;
    base::JSONWriter::WriteWithOptions(
        *arg, base::JSONWriter::OPTIONS_PRETTY_PRINT, &actual_value);

    std::string expected_value;
    base::JSONWriter::WriteWithOptions(
        *dict, base::JSONWriter::OPTIONS_PRETTY_PRINT, &expected_value);

    *result_listener << "Policies are not equal. ";
    *result_listener << "Expected policy: " << expected_value << ". ";
    *result_listener << "Actual policy: " << actual_value << ".";
  }
  return equal;
}

class MockPolicyCallback {
 public:
  MockPolicyCallback() = default;
  ;

  // TODO(lukasza): gmock cannot mock a method taking std::unique_ptr<T>...
  MOCK_METHOD1(OnPolicyUpdatePtr, void(const base::DictionaryValue* policies));
  void OnPolicyUpdate(std::unique_ptr<base::DictionaryValue> policies) {
    OnPolicyUpdatePtr(policies.get());
  }

  MOCK_METHOD0(OnPolicyError, void());

 private:
  DISALLOW_COPY_AND_ASSIGN(MockPolicyCallback);
};

class PolicyWatcherTest : public testing::Test {
 public:
  PolicyWatcherTest() : message_loop_(base::MessageLoop::TYPE_IO) {}

  void SetUp() override {
    // We expect no callbacks unless explicitly specified by individual tests.
    EXPECT_CALL(mock_policy_callback_, OnPolicyUpdatePtr(testing::_)).Times(0);
    EXPECT_CALL(mock_policy_callback_, OnPolicyError()).Times(0);

    // Retaining a raw pointer to keep control over policy contents.
    policy_loader_ =
        new policy::FakeAsyncPolicyLoader(base::ThreadTaskRunnerHandle::Get());
    policy_watcher_ = PolicyWatcher::CreateFromPolicyLoaderForTesting(
        base::WrapUnique(policy_loader_));

    base::ListValue host_domain;
    host_domain.AppendString(kHostDomain);
    base::ListValue client_domain;
    client_domain.AppendString(kClientDomain);
    base::ListValue multiple_host_domains;
    multiple_host_domains.AppendString("a.com");
    multiple_host_domains.AppendString("b.com");
    multiple_host_domains.AppendString("c.com");
    base::ListValue multiple_client_domains;
    multiple_client_domains.AppendString("d.com");
    multiple_client_domains.AppendString("e.com");
    multiple_client_domains.AppendString("f.com");

    nat_true_.SetBoolean(key::kRemoteAccessHostFirewallTraversal, true);
    nat_false_.SetBoolean(key::kRemoteAccessHostFirewallTraversal, false);
    nat_one_.SetInteger(key::kRemoteAccessHostFirewallTraversal, 1);
    nat_one_domain_full_.SetInteger(key::kRemoteAccessHostFirewallTraversal, 1);
    nat_one_domain_full_.Set(key::kRemoteAccessHostDomainList,
                             host_domain.CreateDeepCopy());
    domain_empty_.Set(key::kRemoteAccessHostDomainList,
                      std::make_unique<base::ListValue>());
    domain_full_.Set(key::kRemoteAccessHostDomainList,
                     host_domain.CreateDeepCopy());
    SetDefaults(nat_true_others_default_);
    nat_true_others_default_.SetBoolean(key::kRemoteAccessHostFirewallTraversal,
                                        true);
    SetDefaults(nat_false_others_default_);
    nat_false_others_default_.SetBoolean(
        key::kRemoteAccessHostFirewallTraversal, false);
    SetDefaults(domain_empty_others_default_);
    domain_empty_others_default_.Set(key::kRemoteAccessHostDomainList,
                                     std::make_unique<base::ListValue>());
    SetDefaults(domain_full_others_default_);
    domain_full_others_default_.Set(key::kRemoteAccessHostDomainList,
                                    host_domain.CreateDeepCopy());
    nat_true_domain_empty_.SetBoolean(key::kRemoteAccessHostFirewallTraversal,
                                      true);
    nat_true_domain_empty_.Set(key::kRemoteAccessHostDomainList,
                               std::make_unique<base::ListValue>());
    nat_true_domain_full_.SetBoolean(key::kRemoteAccessHostFirewallTraversal,
                                     true);
    nat_true_domain_full_.Set(key::kRemoteAccessHostDomainList,
                              host_domain.CreateDeepCopy());
    nat_false_domain_empty_.SetBoolean(key::kRemoteAccessHostFirewallTraversal,
                                       false);
    nat_false_domain_empty_.Set(key::kRemoteAccessHostDomainList,
                                std::make_unique<base::ListValue>());
    nat_false_domain_full_.SetBoolean(key::kRemoteAccessHostFirewallTraversal,
                                      false);
    nat_false_domain_full_.Set(key::kRemoteAccessHostDomainList,
                               host_domain.CreateDeepCopy());
    SetDefaults(nat_true_domain_empty_others_default_);
    nat_true_domain_empty_others_default_.SetBoolean(
        key::kRemoteAccessHostFirewallTraversal, true);
    nat_true_domain_empty_others_default_.Set(
        key::kRemoteAccessHostDomainList, std::make_unique<base::ListValue>());
    unknown_policies_.SetString("UnknownPolicyOne", std::string());
    unknown_policies_.SetString("UnknownPolicyTwo", std::string());
    unknown_policies_.SetBoolean("RemoteAccessHostUnknownPolicyThree", true);

    pairing_true_.SetBoolean(key::kRemoteAccessHostAllowClientPairing, true);
    pairing_false_.SetBoolean(key::kRemoteAccessHostAllowClientPairing, false);
    gnubby_auth_true_.SetBoolean(key::kRemoteAccessHostAllowGnubbyAuth, true);
    gnubby_auth_false_.SetBoolean(key::kRemoteAccessHostAllowGnubbyAuth, false);
    relay_true_.SetBoolean(key::kRemoteAccessHostAllowRelayedConnection, true);
    relay_false_.SetBoolean(key::kRemoteAccessHostAllowRelayedConnection,
                            false);
    port_range_full_.SetString(key::kRemoteAccessHostUdpPortRange, kPortRange);
    port_range_empty_.SetString(key::kRemoteAccessHostUdpPortRange,
                                std::string());
    port_range_malformed_.SetString(key::kRemoteAccessHostUdpPortRange,
                                    "malformed");
    port_range_malformed_domain_full_.MergeDictionary(&port_range_malformed_);
    port_range_malformed_domain_full_.Set(key::kRemoteAccessHostDomainList,
                                          host_domain.CreateDeepCopy());

    curtain_true_.SetBoolean(key::kRemoteAccessHostRequireCurtain, true);
    curtain_false_.SetBoolean(key::kRemoteAccessHostRequireCurtain, false);
    username_true_.SetBoolean(key::kRemoteAccessHostMatchUsername, true);
    username_false_.SetBoolean(key::kRemoteAccessHostMatchUsername, false);
    talk_gadget_blah_.SetString(key::kRemoteAccessHostTalkGadgetPrefix, "blah");
    third_party_auth_partial_.SetString(key::kRemoteAccessHostTokenUrl,
                                        "https://token.com");
    third_party_auth_partial_.SetString(
        key::kRemoteAccessHostTokenValidationUrl, "https://validation.com");
    third_party_auth_full_.MergeDictionary(&third_party_auth_partial_);
    third_party_auth_full_.SetString(
        key::kRemoteAccessHostTokenValidationCertificateIssuer,
        "certificate subject");
    third_party_auth_cert_empty_.MergeDictionary(&third_party_auth_partial_);
    third_party_auth_cert_empty_.SetString(
        key::kRemoteAccessHostTokenValidationCertificateIssuer, "");
    remote_assistance_uiaccess_true_.SetBoolean(
        key::kRemoteAccessHostAllowUiAccessForRemoteAssistance, true);
    remote_assistance_uiaccess_false_.SetBoolean(
        key::kRemoteAccessHostAllowUiAccessForRemoteAssistance, false);

    deprecated_policies_.SetString(key::kRemoteAccessHostDomain, kHostDomain);
    deprecated_policies_.SetString(key::kRemoteAccessHostClientDomain,
                                   kClientDomain);
    // Deprecated policies should get converted if new ones aren't present.
    SetDefaults(deprecated_policies_expected_);
    deprecated_policies_expected_.Set(key::kRemoteAccessHostDomainList,
                                      host_domain.CreateDeepCopy());
    deprecated_policies_expected_.Set(key::kRemoteAccessHostClientDomainList,
                                      client_domain.CreateDeepCopy());

    deprecated_and_new_policies_.SetString(key::kRemoteAccessHostDomain,
                                           kHostDomain);
    deprecated_and_new_policies_.SetString(key::kRemoteAccessHostClientDomain,
                                           kClientDomain);
    deprecated_and_new_policies_.Set(key::kRemoteAccessHostDomainList,
                                     multiple_host_domains.CreateDeepCopy());
    deprecated_and_new_policies_.Set(key::kRemoteAccessHostClientDomainList,
                                     multiple_client_domains.CreateDeepCopy());
    // Deprecated policies should just be dropped in new ones are present.
    SetDefaults(deprecated_and_new_policies_expected_);
    deprecated_and_new_policies_expected_.Set(
        key::kRemoteAccessHostDomainList,
        multiple_host_domains.CreateDeepCopy());
    deprecated_and_new_policies_expected_.Set(
        key::kRemoteAccessHostClientDomainList,
        multiple_client_domains.CreateDeepCopy());

    // Empty strings should be treated as not set.
    deprecated_empty_strings_.SetString(key::kRemoteAccessHostDomain, "");
    deprecated_empty_strings_.SetString(key::kRemoteAccessHostClientDomain, "");
  }

  void TearDown() override {
    policy_watcher_.reset();
    policy_loader_ = nullptr;
    base::RunLoop().RunUntilIdle();
  }

 protected:
  void StartWatching() {
    policy_watcher_->StartWatching(
        base::Bind(&MockPolicyCallback::OnPolicyUpdate,
                   base::Unretained(&mock_policy_callback_)),
        base::Bind(&MockPolicyCallback::OnPolicyError,
                   base::Unretained(&mock_policy_callback_)));
    base::RunLoop().RunUntilIdle();
  }

  void SetPolicies(const base::DictionaryValue& dict) {
    // Copy |dict| into |policy_bundle|.
    policy::PolicyNamespace policy_namespace =
        policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME, std::string());
    policy::PolicyBundle policy_bundle;
    policy::PolicyMap& policy_map = policy_bundle.Get(policy_namespace);
    policy_map.LoadFrom(&dict, policy::POLICY_LEVEL_MANDATORY,
                        policy::POLICY_SCOPE_MACHINE,
                        policy::POLICY_SOURCE_CLOUD);

    // Simulate a policy file/registry/preference update.
    policy_loader_->SetPolicies(policy_bundle);
    policy_loader_->PostReloadOnBackgroundThread(true /* force reload asap */);
    base::RunLoop().RunUntilIdle();
  }

  const policy::Schema* GetPolicySchema() {
    return policy_watcher_->GetPolicySchema();
  }

  // TODO(jamiewalch): Update this to use PolicyWatcher::GetDefaultValues()
  const base::DictionaryValue& GetDefaultValues() {
    return *(policy_watcher_->default_values_);
  }

  MOCK_METHOD0(PostPolicyWatcherShutdown, void());

  static const char* kHostDomain;
  static const char* kClientDomain;
  static const char* kPortRange;
  base::MessageLoop message_loop_;
  MockPolicyCallback mock_policy_callback_;

  // |policy_loader_| is owned by |policy_watcher_|. PolicyWatcherTest retains
  // a raw pointer to |policy_loader_| in order to control the simulated / faked
  // policy contents.
  policy::FakeAsyncPolicyLoader* policy_loader_;
  std::unique_ptr<PolicyWatcher> policy_watcher_;

  base::DictionaryValue empty_;
  base::DictionaryValue nat_true_;
  base::DictionaryValue nat_false_;
  base::DictionaryValue nat_one_;
  base::DictionaryValue nat_one_domain_full_;
  base::DictionaryValue domain_empty_;
  base::DictionaryValue domain_full_;
  base::DictionaryValue nat_true_others_default_;
  base::DictionaryValue nat_false_others_default_;
  base::DictionaryValue domain_empty_others_default_;
  base::DictionaryValue domain_full_others_default_;
  base::DictionaryValue nat_true_domain_empty_;
  base::DictionaryValue nat_true_domain_full_;
  base::DictionaryValue nat_false_domain_empty_;
  base::DictionaryValue nat_false_domain_full_;
  base::DictionaryValue nat_true_domain_empty_others_default_;
  base::DictionaryValue unknown_policies_;
  base::DictionaryValue pairing_true_;
  base::DictionaryValue pairing_false_;
  base::DictionaryValue gnubby_auth_true_;
  base::DictionaryValue gnubby_auth_false_;
  base::DictionaryValue relay_true_;
  base::DictionaryValue relay_false_;
  base::DictionaryValue port_range_full_;
  base::DictionaryValue port_range_empty_;
  base::DictionaryValue port_range_malformed_;
  base::DictionaryValue port_range_malformed_domain_full_;
  base::DictionaryValue curtain_true_;
  base::DictionaryValue curtain_false_;
  base::DictionaryValue username_true_;
  base::DictionaryValue username_false_;
  base::DictionaryValue talk_gadget_blah_;
  base::DictionaryValue third_party_auth_full_;
  base::DictionaryValue third_party_auth_partial_;
  base::DictionaryValue third_party_auth_cert_empty_;
  base::DictionaryValue remote_assistance_uiaccess_true_;
  base::DictionaryValue remote_assistance_uiaccess_false_;
  base::DictionaryValue deprecated_policies_;
  base::DictionaryValue deprecated_policies_expected_;
  base::DictionaryValue deprecated_and_new_policies_;
  base::DictionaryValue deprecated_and_new_policies_expected_;
  base::DictionaryValue deprecated_empty_strings_;

 private:
  void SetDefaults(base::DictionaryValue& dict) {
    dict.SetBoolean(key::kRemoteAccessHostFirewallTraversal, true);
    dict.SetBoolean(key::kRemoteAccessHostAllowRelayedConnection, true);
    dict.SetString(key::kRemoteAccessHostUdpPortRange, "");
    dict.Set(key::kRemoteAccessHostClientDomainList,
             std::make_unique<base::ListValue>());
    dict.Set(key::kRemoteAccessHostDomainList,
             std::make_unique<base::ListValue>());
    dict.SetBoolean(key::kRemoteAccessHostMatchUsername, false);
    dict.SetString(key::kRemoteAccessHostTalkGadgetPrefix,
                   kDefaultHostTalkGadgetPrefix);
    dict.SetBoolean(key::kRemoteAccessHostRequireCurtain, false);
    dict.SetString(key::kRemoteAccessHostTokenUrl, "");
    dict.SetString(key::kRemoteAccessHostTokenValidationUrl, "");
    dict.SetString(key::kRemoteAccessHostTokenValidationCertificateIssuer, "");
    dict.SetBoolean(key::kRemoteAccessHostAllowClientPairing, true);
    dict.SetBoolean(key::kRemoteAccessHostAllowGnubbyAuth, true);
    dict.SetBoolean(key::kRemoteAccessHostAllowUiAccessForRemoteAssistance,
                    false);

    ASSERT_THAT(&dict, IsPolicies(&GetDefaultValues()))
        << "Sanity check that defaults expected by the test code "
        << "match what is stored in PolicyWatcher::default_values_";
  }
};

const char* PolicyWatcherTest::kHostDomain = "google.com";
const char* PolicyWatcherTest::kClientDomain = "client.com";
const char* PolicyWatcherTest::kPortRange = "12400-12409";

TEST_F(PolicyWatcherTest, None) {
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));

  SetPolicies(empty_);
  StartWatching();
}

TEST_F(PolicyWatcherTest, NatTrue) {
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));

  SetPolicies(nat_true_);
  StartWatching();
}

TEST_F(PolicyWatcherTest, NatFalse) {
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&nat_false_others_default_)));

  SetPolicies(nat_false_);
  StartWatching();
}

TEST_F(PolicyWatcherTest, NatWrongType) {
  EXPECT_CALL(mock_policy_callback_, OnPolicyError());

  SetPolicies(nat_one_);
  StartWatching();
}

// This test verifies that a mistyped policy value is still detected
// even though it doesn't change during the second SetPolicies call.
TEST_F(PolicyWatcherTest, NatWrongTypeThenIrrelevantChange) {
  EXPECT_CALL(mock_policy_callback_, OnPolicyError()).Times(2);

  SetPolicies(nat_one_);
  StartWatching();
  SetPolicies(nat_one_domain_full_);
}

// This test verifies that a malformed policy value is still detected
// even though it doesn't change during the second SetPolicies call.
TEST_F(PolicyWatcherTest, PortRangeMalformedThenIrrelevantChange) {
  EXPECT_CALL(mock_policy_callback_, OnPolicyError()).Times(2);

  SetPolicies(port_range_malformed_);
  StartWatching();
  SetPolicies(port_range_malformed_domain_full_);
}

TEST_F(PolicyWatcherTest, DomainEmpty) {
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&domain_empty_others_default_)));

  SetPolicies(domain_empty_);
  StartWatching();
}

TEST_F(PolicyWatcherTest, DomainFull) {
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&domain_full_others_default_)));

  SetPolicies(domain_full_);
  StartWatching();
}

TEST_F(PolicyWatcherTest, NatNoneThenTrue) {
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));

  SetPolicies(empty_);
  StartWatching();
  SetPolicies(nat_true_);
}

TEST_F(PolicyWatcherTest, NatNoneThenTrueThenTrue) {
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));

  SetPolicies(empty_);
  StartWatching();
  SetPolicies(nat_true_);
  SetPolicies(nat_true_);
}

TEST_F(PolicyWatcherTest, NatNoneThenTrueThenTrueThenFalse) {
  testing::InSequence sequence;
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&nat_false_)));

  SetPolicies(empty_);
  StartWatching();
  SetPolicies(nat_true_);
  SetPolicies(nat_true_);
  SetPolicies(nat_false_);
}

TEST_F(PolicyWatcherTest, NatNoneThenFalse) {
  testing::InSequence sequence;
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&nat_false_)));

  SetPolicies(empty_);
  StartWatching();
  SetPolicies(nat_false_);
}

TEST_F(PolicyWatcherTest, NatNoneThenFalseThenTrue) {
  testing::InSequence sequence;
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&nat_false_)));
  EXPECT_CALL(mock_policy_callback_, OnPolicyUpdatePtr(IsPolicies(&nat_true_)));

  SetPolicies(empty_);
  StartWatching();
  SetPolicies(nat_false_);
  SetPolicies(nat_true_);
}

TEST_F(PolicyWatcherTest, ChangeOneRepeatedlyThenTwo) {
  testing::InSequence sequence;
  EXPECT_CALL(
      mock_policy_callback_,
      OnPolicyUpdatePtr(IsPolicies(&nat_true_domain_empty_others_default_)));
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&domain_full_)));
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&nat_false_)));
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&domain_empty_)));
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&nat_true_domain_full_)));

  SetPolicies(nat_true_domain_empty_);
  StartWatching();
  SetPolicies(nat_true_domain_full_);
  SetPolicies(nat_false_domain_full_);
  SetPolicies(nat_false_domain_empty_);
  SetPolicies(nat_true_domain_full_);
}

TEST_F(PolicyWatcherTest, FilterUnknownPolicies) {
  testing::InSequence sequence;
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));

  SetPolicies(empty_);
  StartWatching();
  SetPolicies(unknown_policies_);
  SetPolicies(empty_);
}

class MisspelledPolicyTest : public PolicyWatcherTest,
                             public ::testing::WithParamInterface<const char*> {
};

// Verify that a misspelled policy causes a warning written to the log.
TEST_P(MisspelledPolicyTest, WarningLogged) {
  const char* misspelled_policy_name = GetParam();
  base::test::MockLog mock_log;

  ON_CALL(mock_log, Log(testing::_, testing::_, testing::_, testing::_,
                        testing::_)).WillByDefault(testing::Return(true));

  EXPECT_CALL(mock_log,
              Log(logging::LOG_WARNING, testing::_, testing::_, testing::_,
                  testing::HasSubstr(misspelled_policy_name))).Times(1);

  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));

  base::DictionaryValue misspelled_policies;
  misspelled_policies.SetString(misspelled_policy_name, "some test value");
  mock_log.StartCapturingLogs();

  SetPolicies(misspelled_policies);
  StartWatching();

  mock_log.StopCapturingLogs();
}

INSTANTIATE_TEST_CASE_P(
    PolicyWatcherTest,
    MisspelledPolicyTest,
    ::testing::Values("RemoteAccessHostDomainX",
                      "XRemoteAccessHostDomain",
                      "RemoteAccessHostdomain",
                      "RemoteAccessHostPolicyForFutureVersion"));

TEST_F(PolicyWatcherTest, PairingFalseThenTrue) {
  testing::InSequence sequence;
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&pairing_false_)));
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&pairing_true_)));

  SetPolicies(empty_);
  StartWatching();
  SetPolicies(pairing_false_);
  SetPolicies(pairing_true_);
}

TEST_F(PolicyWatcherTest, GnubbyAuth) {
  testing::InSequence sequence;
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&gnubby_auth_false_)));
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&gnubby_auth_true_)));

  SetPolicies(empty_);
  StartWatching();
  SetPolicies(gnubby_auth_false_);
  SetPolicies(gnubby_auth_true_);
}

TEST_F(PolicyWatcherTest, RemoteAssistanceUiAccess) {
  testing::InSequence sequence;
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
#if defined(OS_WIN)
  // This setting only affects Windows, it is ignored on other platforms so the
  // 2 SetPolicies calls won't result in any calls to OnPolicyUpdate.
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&remote_assistance_uiaccess_true_)));
  EXPECT_CALL(
      mock_policy_callback_,
      OnPolicyUpdatePtr(IsPolicies(&remote_assistance_uiaccess_false_)));
#endif  // defined(OS_WIN)

  SetPolicies(empty_);
  StartWatching();
  SetPolicies(remote_assistance_uiaccess_true_);
  SetPolicies(remote_assistance_uiaccess_false_);
}

TEST_F(PolicyWatcherTest, Relay) {
  testing::InSequence sequence;
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&relay_false_)));
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&relay_true_)));

  SetPolicies(empty_);
  StartWatching();
  SetPolicies(relay_false_);
  SetPolicies(relay_true_);
}

TEST_F(PolicyWatcherTest, Curtain) {
  testing::InSequence sequence;
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&curtain_true_)));
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&curtain_false_)));

  SetPolicies(empty_);
  StartWatching();
  SetPolicies(curtain_true_);
  SetPolicies(curtain_false_);
}

TEST_F(PolicyWatcherTest, MatchUsername) {
  testing::InSequence sequence;
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
#if !defined(OS_WIN)
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&username_true_)));
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&username_false_)));
#else
// On Windows the MatchUsername policy is ignored and therefore the 2
// SetPolicies calls won't result in any calls to OnPolicyUpdate.
#endif

  SetPolicies(empty_);
  StartWatching();
  SetPolicies(username_true_);
  SetPolicies(username_false_);
}

TEST_F(PolicyWatcherTest, TalkGadgetPrefix) {
  testing::InSequence sequence;
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&talk_gadget_blah_)));

  SetPolicies(empty_);
  StartWatching();
  SetPolicies(talk_gadget_blah_);
}

TEST_F(PolicyWatcherTest, ThirdPartyAuthFull) {
  testing::InSequence sequence;
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&third_party_auth_full_)));

  SetPolicies(empty_);
  StartWatching();
  SetPolicies(third_party_auth_full_);
}

// This test verifies what happens when only 1 out of 3 third-party auth
// policies changes.  Without the other 2 policy values such policy values
// combination is invalid (i.e. cannot have TokenUrl without
// TokenValidationUrl) and can trigger OnPolicyError unless PolicyWatcher
// implementation is careful around this scenario.
TEST_F(PolicyWatcherTest, ThirdPartyAuthPartialToFull) {
  testing::InSequence sequence;
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&third_party_auth_cert_empty_)));
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&third_party_auth_full_)));

  SetPolicies(empty_);
  StartWatching();
  SetPolicies(third_party_auth_partial_);
  SetPolicies(third_party_auth_full_);
}

TEST_F(PolicyWatcherTest, UdpPortRange) {
  testing::InSequence sequence;
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&port_range_full_)));
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&port_range_empty_)));

  SetPolicies(empty_);
  StartWatching();
  SetPolicies(port_range_full_);
  SetPolicies(port_range_empty_);
}

TEST_F(PolicyWatcherTest, PolicySchemaAndPolicyWatcherShouldBeInSync) {
  // This test verifies that
  // 1) policy schema (generated out of policy_templates.json)
  // and
  // 2) PolicyWatcher's code (i.e. contents of the |default_values_| field)
  // are kept in-sync.

  std::map<std::string, base::Value::Type> expected_schema;
  for (base::DictionaryValue::Iterator i(GetDefaultValues()); !i.IsAtEnd();
       i.Advance()) {
    expected_schema[i.key()] = i.value().type();
  }
#if defined(OS_WIN)
  // RemoteAccessHostMatchUsername is marked in policy_templates.json as not
  // supported on Windows and therefore is (by design) excluded from the schema.
  expected_schema.erase(key::kRemoteAccessHostMatchUsername);
#else  // !defined(OS_WIN)
  // RemoteAssistanceHostAllowUiAccess does not exist on non-Windows platforms.
  expected_schema.erase(key::kRemoteAccessHostAllowUiAccessForRemoteAssistance);
#endif

  std::map<std::string, base::Value::Type> actual_schema;
  const policy::Schema* schema = GetPolicySchema();
  ASSERT_TRUE(schema->valid());
  for (auto it = schema->GetPropertiesIterator(); !it.IsAtEnd(); it.Advance()) {
    std::string key = it.key();
    if (key.find("RemoteAccessHost") == std::string::npos) {
      // For now PolicyWatcher::GetPolicySchema() mixes Chrome and Chromoting
      // policies, so we have to skip them here.
      continue;
    }
    if (key == policy::key::kRemoteAccessHostDomain ||
        key == policy::key::kRemoteAccessHostClientDomain) {
      // These policies are deprecated and get removed during normalization
      continue;
    }
    actual_schema[key] = it.schema().type();
  }

  EXPECT_THAT(actual_schema, testing::ContainerEq(expected_schema));
}

TEST_F(PolicyWatcherTest, SchemaTypeCheck) {
  const policy::Schema* schema = GetPolicySchema();
  ASSERT_TRUE(schema->valid());

  // Check one, random "string" policy to see if the type propagated correctly
  // from policy_templates.json file.
  const policy::Schema string_schema =
      schema->GetKnownProperty("RemoteAccessHostDomain");
  EXPECT_TRUE(string_schema.valid());
  EXPECT_EQ(string_schema.type(), base::Value::Type::STRING);

  // And check one, random "boolean" policy to see if the type propagated
  // correctly from policy_templates.json file.
  const policy::Schema boolean_schema =
      schema->GetKnownProperty("RemoteAccessHostRequireCurtain");
  EXPECT_TRUE(boolean_schema.valid());
  EXPECT_EQ(boolean_schema.type(), base::Value::Type::BOOLEAN);
}

TEST_F(PolicyWatcherTest, DeprecatedOnly) {
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&deprecated_policies_expected_)));
  SetPolicies(deprecated_policies_);
  StartWatching();
}

TEST_F(PolicyWatcherTest, DeprecatedAndNew) {
  EXPECT_CALL(
      mock_policy_callback_,
      OnPolicyUpdatePtr(IsPolicies(&deprecated_and_new_policies_expected_)));
  SetPolicies(deprecated_and_new_policies_);
  StartWatching();
}

TEST_F(PolicyWatcherTest, DeprecatedEmpty) {
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&GetDefaultValues())));
  SetPolicies(deprecated_empty_strings_);
  StartWatching();
}

TEST_F(PolicyWatcherTest, GetCurrentPolicies) {
  testing::InSequence sequence;
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
  EXPECT_CALL(mock_policy_callback_,
              OnPolicyUpdatePtr(IsPolicies(&nat_false_)));

  StartWatching();
  SetPolicies(nat_false_);
  std::unique_ptr<base::DictionaryValue> current_policies =
      policy_watcher_->GetCurrentPolicies();
  ASSERT_TRUE(*current_policies == nat_false_others_default_);
}

TEST_F(PolicyWatcherTest, GetCurrentPoliciesError) {
  EXPECT_CALL(mock_policy_callback_, OnPolicyError());

  SetPolicies(nat_one_);
  StartWatching();
  std::unique_ptr<base::DictionaryValue> current_policies =
      policy_watcher_->GetCurrentPolicies();
  ASSERT_EQ(0u, current_policies->size());
}

}  // namespace remoting
