// Copyright 2014 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/location.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/browser/extensions/extension_install_checker.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace extensions {

namespace {

const BlacklistState kBlacklistStateError = BLACKLISTED_MALWARE;
const char kDummyRequirementsError[] = "Requirements error";
const char kDummyPolicyError[] = "Cannot install extension";

const char kDummyPolicyError2[] = "Another policy error";
const char kDummyRequirementsError2[] = "Another requirements error";
const BlacklistState kBlacklistState2 = BLACKLISTED_SECURITY_VULNERABILITY;

}  // namespace

// Stubs most of the checks since we are interested in validating the logic in
// the install checker. This class implements a synchronous version of all
// checks.
class ExtensionInstallCheckerForTest : public ExtensionInstallChecker {
 public:
  ExtensionInstallCheckerForTest()
      : ExtensionInstallChecker(NULL),
        requirements_check_called_(false),
        blacklist_check_called_(false),
        policy_check_called_(false),
        blacklist_state_(NOT_BLACKLISTED) {}

  ~ExtensionInstallCheckerForTest() override {}

  void set_requirements_error(const std::string& error) {
    requirements_error_ = error;
  }
  void set_policy_check_error(const std::string& error) {
    policy_check_error_ = error;
  }
  void set_blacklist_state(BlacklistState state) { blacklist_state_ = state; }

  bool requirements_check_called() const { return requirements_check_called_; }
  bool blacklist_check_called() const { return blacklist_check_called_; }
  bool policy_check_called() const { return policy_check_called_; }

  void MockCheckRequirements(int sequence_number) {
    std::vector<std::string> errors;
    if (!requirements_error_.empty())
      errors.push_back(requirements_error_);
    OnRequirementsCheckDone(sequence_number, errors);
  }

  void MockCheckBlacklistState(int sequence_number) {
    OnBlacklistStateCheckDone(sequence_number, blacklist_state_);
  }

 protected:
  void CheckRequirements() override {
    requirements_check_called_ = true;
    MockCheckRequirements(current_sequence_number());
  }

  void CheckManagementPolicy() override {
    policy_check_called_ = true;
    OnManagementPolicyCheckDone(policy_check_error_.empty(),
                                policy_check_error_);
  }

  void CheckBlacklistState() override {
    blacklist_check_called_ = true;
    MockCheckBlacklistState(current_sequence_number());
  }

  void ResetResults() override {
    ExtensionInstallChecker::ResetResults();

    requirements_check_called_ = false;
    blacklist_check_called_ = false;
    policy_check_called_ = false;
  }

  bool requirements_check_called_;
  bool blacklist_check_called_;
  bool policy_check_called_;

  // Dummy errors for testing.
  std::string requirements_error_;
  std::string policy_check_error_;
  BlacklistState blacklist_state_;
};

// This class implements asynchronous mocks of the requirements and blacklist
// checks.
class ExtensionInstallCheckerAsync : public ExtensionInstallCheckerForTest {
 protected:
  void CheckRequirements() override {
    requirements_check_called_ = true;

    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE,
        base::Bind(&ExtensionInstallCheckerForTest::MockCheckRequirements,
                   base::Unretained(this), current_sequence_number()));
  }

  void CheckBlacklistState() override {
    blacklist_check_called_ = true;

    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE,
        base::Bind(&ExtensionInstallCheckerForTest::MockCheckBlacklistState,
                   base::Unretained(this), current_sequence_number()));
  }
};

class CheckObserver {
 public:
  CheckObserver() : result_(0), call_count_(0) {}

  int result() const { return result_; }
  int call_count() const { return call_count_; }

  void OnChecksComplete(int checks_failed) {
    result_ = checks_failed;
    ++call_count_;
  }

  void Wait() {
    if (call_count_)
      return;

    base::RunLoop().RunUntilIdle();
  }

 private:
  int result_;
  int call_count_;
};

class ExtensionInstallCheckerTest : public testing::Test {
 public:
  ExtensionInstallCheckerTest() {}
  ~ExtensionInstallCheckerTest() override {}

  void RunSecondInvocation(ExtensionInstallCheckerForTest* checker,
                           int checks_failed) {
    EXPECT_GT(checks_failed, 0);
    EXPECT_FALSE(checker->is_running());
    ValidateExpectedCalls(ExtensionInstallChecker::CHECK_ALL, *checker);

    // Set up different return values.
    checker->set_blacklist_state(kBlacklistState2);
    checker->set_policy_check_error(kDummyPolicyError2);
    checker->set_requirements_error(kDummyRequirementsError2);

    // Run the install checker again and ensure the second set of return values
    // is received.
    checker->Start(
        ExtensionInstallChecker::CHECK_ALL,
        false /* fail fast */,
        base::Bind(&ExtensionInstallCheckerTest::ValidateSecondInvocation,
                   base::Unretained(this),
                   checker));
  }

  void ValidateSecondInvocation(ExtensionInstallCheckerForTest* checker,
                                int checks_failed) {
    EXPECT_FALSE(checker->is_running());
    EXPECT_EQ(ExtensionInstallChecker::CHECK_REQUIREMENTS |
                  ExtensionInstallChecker::CHECK_MANAGEMENT_POLICY,
              checks_failed);
    ValidateExpectedCalls(ExtensionInstallChecker::CHECK_ALL, *checker);

    EXPECT_EQ(kBlacklistState2, checker->blacklist_state());
    ExpectPolicyError(kDummyPolicyError2, *checker);
    ExpectRequirementsError(kDummyRequirementsError2, *checker);
  }

 protected:
  void SetAllErrors(ExtensionInstallCheckerForTest* checker) {
    checker->set_blacklist_state(kBlacklistStateError);
    checker->set_policy_check_error(kDummyPolicyError);
    checker->set_requirements_error(kDummyRequirementsError);
  }

  void ValidateExpectedCalls(int call_mask,
                             const ExtensionInstallCheckerForTest& checker) {
    bool expect_blacklist_checked =
        (call_mask & ExtensionInstallChecker::CHECK_BLACKLIST) != 0;
    bool expect_requirements_checked =
        (call_mask & ExtensionInstallChecker::CHECK_REQUIREMENTS) != 0;
    bool expect_policy_checked =
        (call_mask & ExtensionInstallChecker::CHECK_MANAGEMENT_POLICY) != 0;
    EXPECT_EQ(expect_blacklist_checked, checker.blacklist_check_called());
    EXPECT_EQ(expect_policy_checked, checker.policy_check_called());
    EXPECT_EQ(expect_requirements_checked, checker.requirements_check_called());
  }

  void ExpectRequirementsPass(const ExtensionInstallCheckerForTest& checker) {
    EXPECT_TRUE(checker.requirement_errors().empty());
  }

  void ExpectRequirementsError(const char* expected_error,
                               const ExtensionInstallCheckerForTest& checker) {
    EXPECT_FALSE(checker.requirement_errors().empty());
    EXPECT_EQ(std::string(expected_error),
              checker.requirement_errors().front());
  }

  void ExpectRequirementsError(const ExtensionInstallCheckerForTest& checker) {
    ExpectRequirementsError(kDummyRequirementsError, checker);
  }

  void ExpectBlacklistPass(const ExtensionInstallCheckerForTest& checker) {
    EXPECT_EQ(NOT_BLACKLISTED, checker.blacklist_state());
  }

  void ExpectBlacklistError(const ExtensionInstallCheckerForTest& checker) {
    EXPECT_EQ(kBlacklistStateError, checker.blacklist_state());
  }

  void ExpectPolicyPass(const ExtensionInstallCheckerForTest& checker) {
    EXPECT_TRUE(checker.policy_allows_load());
    EXPECT_TRUE(checker.policy_error().empty());
  }

  void ExpectPolicyError(const char* expected_error,
                         const ExtensionInstallCheckerForTest& checker) {
    EXPECT_FALSE(checker.policy_allows_load());
    EXPECT_FALSE(checker.policy_error().empty());
    EXPECT_EQ(std::string(expected_error), checker.policy_error());
  }

  void ExpectPolicyError(const ExtensionInstallCheckerForTest& checker) {
    ExpectPolicyError(kDummyPolicyError, checker);
  }

  void RunChecker(ExtensionInstallCheckerForTest* checker,
                  bool fail_fast,
                  int checks_to_run,
                  int expected_checks_run,
                  int expected_result) {
    CheckObserver observer;
    checker->Start(checks_to_run,
                   fail_fast,
                   base::Bind(&CheckObserver::OnChecksComplete,
                              base::Unretained(&observer)));
    observer.Wait();

    EXPECT_FALSE(checker->is_running());
    EXPECT_EQ(expected_result, observer.result());
    EXPECT_EQ(1, observer.call_count());
    ValidateExpectedCalls(expected_checks_run, *checker);
  }

  void DoRunAllChecksPass(ExtensionInstallCheckerForTest* checker) {
    RunChecker(checker,
               false /* fail fast */,
               ExtensionInstallChecker::CHECK_ALL,
               ExtensionInstallChecker::CHECK_ALL,
               0);

    ExpectRequirementsPass(*checker);
    ExpectPolicyPass(*checker);
    ExpectBlacklistPass(*checker);
  }

  void DoRunAllChecksFail(ExtensionInstallCheckerForTest* checker) {
    SetAllErrors(checker);
    RunChecker(checker,
               false /* fail fast */,
               ExtensionInstallChecker::CHECK_ALL,
               ExtensionInstallChecker::CHECK_ALL,
               ExtensionInstallChecker::CHECK_ALL);

    ExpectRequirementsError(*checker);
    ExpectPolicyError(*checker);
    ExpectBlacklistError(*checker);
  }

  void DoRunSubsetOfChecks(ExtensionInstallCheckerForTest* checker) {
    // Test check set 1.
    int tests_to_run = ExtensionInstallChecker::CHECK_MANAGEMENT_POLICY |
                       ExtensionInstallChecker::CHECK_REQUIREMENTS;
    SetAllErrors(checker);
    RunChecker(checker, false, tests_to_run, tests_to_run, tests_to_run);

    ExpectRequirementsError(*checker);
    ExpectPolicyError(*checker);
    ExpectBlacklistPass(*checker);

    // Test check set 2.
    tests_to_run = ExtensionInstallChecker::CHECK_BLACKLIST |
                   ExtensionInstallChecker::CHECK_REQUIREMENTS;
    SetAllErrors(checker);
    RunChecker(checker, false, tests_to_run, tests_to_run, tests_to_run);

    ExpectRequirementsError(*checker);
    ExpectPolicyPass(*checker);
    ExpectBlacklistError(*checker);

    // Test a single check.
    tests_to_run = ExtensionInstallChecker::CHECK_BLACKLIST;
    SetAllErrors(checker);
    RunChecker(checker, false, tests_to_run, tests_to_run, tests_to_run);

    ExpectRequirementsPass(*checker);
    ExpectPolicyPass(*checker);
    ExpectBlacklistError(*checker);
  }

 private:
  // A message loop is required for the asynchronous tests.
  base::MessageLoop message_loop;
};

class ExtensionInstallCheckerMultipleInvocationTest
    : public ExtensionInstallCheckerTest {
 public:
  ExtensionInstallCheckerMultipleInvocationTest() : callback_count_(0) {}
  ~ExtensionInstallCheckerMultipleInvocationTest() override {}

  void RunSecondInvocation(ExtensionInstallCheckerForTest* checker,
                           int checks_failed) {
    ASSERT_EQ(0, callback_count_);
    ++callback_count_;
    EXPECT_FALSE(checker->is_running());
    EXPECT_GT(checks_failed, 0);
    ValidateExpectedCalls(ExtensionInstallChecker::CHECK_ALL, *checker);

    // Set up different return values.
    checker->set_blacklist_state(kBlacklistState2);
    checker->set_policy_check_error(kDummyPolicyError2);
    checker->set_requirements_error(kDummyRequirementsError2);

    // Run the install checker again and ensure the second set of return values
    // is received.
    checker->Start(ExtensionInstallChecker::CHECK_ALL,
                   false /* fail fast */,
                   base::Bind(&ExtensionInstallCheckerMultipleInvocationTest::
                                  ValidateSecondInvocation,
                              base::Unretained(this),
                              checker));
  }

  void ValidateSecondInvocation(ExtensionInstallCheckerForTest* checker,
                                int checks_failed) {
    ASSERT_EQ(1, callback_count_);
    EXPECT_FALSE(checker->is_running());
    EXPECT_EQ(ExtensionInstallChecker::CHECK_REQUIREMENTS |
                  ExtensionInstallChecker::CHECK_MANAGEMENT_POLICY,
              checks_failed);
    ValidateExpectedCalls(ExtensionInstallChecker::CHECK_ALL, *checker);

    EXPECT_EQ(kBlacklistState2, checker->blacklist_state());
    ExpectPolicyError(kDummyPolicyError2, *checker);
    ExpectRequirementsError(kDummyRequirementsError2, *checker);
  }

 private:
  int callback_count_;
};

// Test the case where all tests pass.
TEST_F(ExtensionInstallCheckerTest, AllSucceeded) {
  ExtensionInstallCheckerForTest sync_checker;
  DoRunAllChecksPass(&sync_checker);

  ExtensionInstallCheckerAsync async_checker;
  DoRunAllChecksPass(&async_checker);
}

// Test the case where all tests fail.
TEST_F(ExtensionInstallCheckerTest, AllFailed) {
  ExtensionInstallCheckerForTest sync_checker;
  DoRunAllChecksFail(&sync_checker);

  ExtensionInstallCheckerAsync async_checker;
  DoRunAllChecksFail(&async_checker);
}

// Test running only a subset of tests.
TEST_F(ExtensionInstallCheckerTest, RunSubsetOfChecks) {
  ExtensionInstallCheckerForTest sync_checker;
  ExtensionInstallCheckerAsync async_checker;
  DoRunSubsetOfChecks(&sync_checker);
  DoRunSubsetOfChecks(&async_checker);
}

// Test fail fast with synchronous callbacks.
TEST_F(ExtensionInstallCheckerTest, FailFastSync) {
  // This test assumes some internal knowledge of the implementation - that
  // the policy check runs first.
  ExtensionInstallCheckerForTest checker;
  SetAllErrors(&checker);
  RunChecker(&checker,
             true /* fail fast */,
             ExtensionInstallChecker::CHECK_ALL,
             ExtensionInstallChecker::CHECK_MANAGEMENT_POLICY,
             ExtensionInstallChecker::CHECK_MANAGEMENT_POLICY);

  ExpectRequirementsPass(checker);
  ExpectPolicyError(checker);
  ExpectBlacklistPass(checker);

  // This test assumes some internal knowledge of the implementation - that
  // the requirements check runs before the blacklist check.
  SetAllErrors(&checker);
  RunChecker(&checker,
             true /* fail fast */,
             ExtensionInstallChecker::CHECK_REQUIREMENTS |
                 ExtensionInstallChecker::CHECK_BLACKLIST,
             ExtensionInstallChecker::CHECK_REQUIREMENTS,
             ExtensionInstallChecker::CHECK_REQUIREMENTS);

  ExpectRequirementsError(checker);
  ExpectPolicyPass(checker);
  ExpectBlacklistPass(checker);
}

// Test fail fast with asynchronous callbacks.
TEST_F(ExtensionInstallCheckerTest, FailFastAsync) {
  // This test assumes some internal knowledge of the implementation - that
  // the requirements check runs before the blacklist check. Both checks should
  // be called, but the requirements check callback arrives first and the
  // blacklist result will be discarded.
  ExtensionInstallCheckerAsync checker;
  SetAllErrors(&checker);

  // The policy check is synchronous and needs to pass for the other tests to
  // run.
  checker.set_policy_check_error(std::string());

  RunChecker(&checker,
             true /* fail fast */,
             ExtensionInstallChecker::CHECK_ALL,
             ExtensionInstallChecker::CHECK_ALL,
             ExtensionInstallChecker::CHECK_REQUIREMENTS);

  ExpectRequirementsError(checker);
  ExpectPolicyPass(checker);
  ExpectBlacklistPass(checker);
}

// Test multiple invocations of the install checker. Wait for all checks to
// complete.
TEST_F(ExtensionInstallCheckerMultipleInvocationTest, CompleteAll) {
  ExtensionInstallCheckerAsync checker;
  SetAllErrors(&checker);

  // Start the second check as soon as the callback of the first run is invoked.
  checker.Start(
      ExtensionInstallChecker::CHECK_ALL,
      false /* fail fast */,
      base::Bind(
          &ExtensionInstallCheckerMultipleInvocationTest::RunSecondInvocation,
          base::Unretained(this),
          &checker));
  base::RunLoop().RunUntilIdle();
}

// Test multiple invocations of the install checker and fail fast.
TEST_F(ExtensionInstallCheckerMultipleInvocationTest, FailFast) {
  ExtensionInstallCheckerAsync checker;
  SetAllErrors(&checker);

  // The policy check is synchronous and needs to pass for the other tests to
  // run.
  checker.set_policy_check_error(std::string());

  // Start the second check as soon as the callback of the first run is invoked.
  checker.Start(
      ExtensionInstallChecker::CHECK_ALL,
      true /* fail fast */,
      base::Bind(
          &ExtensionInstallCheckerMultipleInvocationTest::RunSecondInvocation,
          base::Unretained(this),
          &checker));
  base::RunLoop().RunUntilIdle();
}

}  // namespace extensions
