// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "extensions/browser/blocklist.h"

#include "base/functional/bind.h"
#include "base/run_loop.h"
#include "base/task/single_thread_task_runner.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/test_browser_context.h"
#include "extensions/browser/blocklist_state_fetcher.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extensions_browser_client.h"
#include "extensions/browser/fake_safe_browsing_database_manager.h"
#include "extensions/browser/scoped_database_manager_for_test.h"
#include "extensions/browser/test_blocklist.h"
#include "extensions/browser/test_blocklist_state_fetcher.h"
#include "extensions/browser/test_extension_prefs.h"
#include "extensions/browser/test_extensions_browser_client.h"
#include "extensions/common/extension_id.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace extensions {
namespace {

class BlocklistTest : public testing::Test {
 public:
  BlocklistTest()
      : test_prefs_(base::SingleThreadTaskRunner::GetCurrentDefault(),
                    std::make_unique<content::TestBrowserContext>()) {
    ExtensionsBrowserClient::Set(&extensions_browser_client_);
    extensions_browser_client_.SetMainContext(browser_context());
  }

 protected:
  ExtensionId AddExtension(const ExtensionId& id) {
    return test_prefs_.AddExtension(id)->id();
  }

  content::BrowserContext* browser_context() {
    return test_prefs_.browser_context();
  }

  void TearDown() override {
    BrowserContextDependencyManager::GetInstance()
        ->DestroyBrowserContextServices(browser_context());
    ExtensionsBrowserClient::Set(nullptr);

    testing::Test::TearDown();
  }

 private:
  content::BrowserTaskEnvironment task_environment_;
  TestExtensionPrefs test_prefs_;
  TestExtensionsBrowserClient extensions_browser_client_;
};

template <typename T>
void Assign(T* to, const T& from) {
  *to = from;
}

}  // namespace

TEST_F(BlocklistTest, OnlyIncludesRequestedIDs) {
  ExtensionId a = AddExtension("a");
  ExtensionId b = AddExtension("b");
  ExtensionId c = AddExtension("c");

  Blocklist blocklist(browser_context());
  TestBlocklist tester(&blocklist);
  tester.SetBlocklistState(a, BLOCKLISTED_MALWARE, false);
  tester.SetBlocklistState(b, BLOCKLISTED_MALWARE, false);

  EXPECT_EQ(BLOCKLISTED_MALWARE, tester.GetBlocklistState(a));
  EXPECT_EQ(BLOCKLISTED_MALWARE, tester.GetBlocklistState(b));
  EXPECT_EQ(NOT_BLOCKLISTED, tester.GetBlocklistState(c));

  std::set<ExtensionId> blocklisted_ids;
  blocklist.GetMalwareIDs(
      {a, c}, base::BindOnce(&Assign<std::set<ExtensionId>>, &blocklisted_ids));
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ((std::set<ExtensionId>{a}), blocklisted_ids);
}

TEST_F(BlocklistTest, SafeBrowsing) {
  ExtensionId a = AddExtension("a");

  Blocklist blocklist(browser_context());
  TestBlocklist tester(&blocklist);
  tester.DisableSafeBrowsing();

  EXPECT_EQ(NOT_BLOCKLISTED, tester.GetBlocklistState(a));

  tester.SetBlocklistState(a, BLOCKLISTED_MALWARE, false);
  // The manager is still disabled at this point, so it won't be blocklisted.
  EXPECT_EQ(NOT_BLOCKLISTED, tester.GetBlocklistState(a));

  tester.EnableSafeBrowsing();
  tester.NotifyUpdate();
  base::RunLoop().RunUntilIdle();
  // Now it should be.
  EXPECT_EQ(BLOCKLISTED_MALWARE, tester.GetBlocklistState(a));

  tester.Clear(true);
  // Safe browsing blocklist empty, now enabled.
  EXPECT_EQ(NOT_BLOCKLISTED, tester.GetBlocklistState(a));
}

// Test getting different blocklist states from Blocklist.
TEST_F(BlocklistTest, GetBlocklistStates) {
  Blocklist blocklist(browser_context());
  TestBlocklist tester(&blocklist);

  ExtensionId a = AddExtension("a");
  ExtensionId b = AddExtension("b");
  ExtensionId c = AddExtension("c");
  ExtensionId d = AddExtension("d");
  ExtensionId e = AddExtension("e");

  tester.SetBlocklistState(a, BLOCKLISTED_MALWARE, false);
  tester.SetBlocklistState(b, BLOCKLISTED_SECURITY_VULNERABILITY, false);
  tester.SetBlocklistState(c, BLOCKLISTED_CWS_POLICY_VIOLATION, false);
  tester.SetBlocklistState(d, BLOCKLISTED_POTENTIALLY_UNWANTED, false);

  Blocklist::BlocklistStateMap states_abc;
  Blocklist::BlocklistStateMap states_bcd;
  blocklist.GetBlocklistedIDs(
      {a, b, c, e},
      base::BindOnce(&Assign<Blocklist::BlocklistStateMap>, &states_abc));
  blocklist.GetBlocklistedIDs(
      {b, c, d, e},
      base::BindOnce(&Assign<Blocklist::BlocklistStateMap>, &states_bcd));
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(BLOCKLISTED_MALWARE, states_abc[a]);
  EXPECT_EQ(BLOCKLISTED_SECURITY_VULNERABILITY, states_abc[b]);
  EXPECT_EQ(BLOCKLISTED_CWS_POLICY_VIOLATION, states_abc[c]);
  EXPECT_EQ(BLOCKLISTED_SECURITY_VULNERABILITY, states_bcd[b]);
  EXPECT_EQ(BLOCKLISTED_CWS_POLICY_VIOLATION, states_bcd[c]);
  EXPECT_EQ(BLOCKLISTED_POTENTIALLY_UNWANTED, states_bcd[d]);
  EXPECT_EQ(0U, states_abc.count(e));
  EXPECT_EQ(0U, states_bcd.count(e));

  int old_request_count = tester.fetcher()->request_count();
  Blocklist::BlocklistStateMap states_ad;
  blocklist.GetBlocklistedIDs(
      {a, d, e},
      base::BindOnce(&Assign<Blocklist::BlocklistStateMap>, &states_ad));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(BLOCKLISTED_MALWARE, states_ad[a]);
  EXPECT_EQ(BLOCKLISTED_POTENTIALLY_UNWANTED, states_ad[d]);
  EXPECT_EQ(0U, states_ad.count(e));
  EXPECT_EQ(old_request_count, tester.fetcher()->request_count());
}

// Test both Blocklist and BlocklistStateFetcher by requesting the blocklist
// states, sending fake requests and parsing the responses.
TEST_F(BlocklistTest, FetchBlocklistStates) {
  Blocklist blocklist(browser_context());
  scoped_refptr<FakeSafeBrowsingDatabaseManager> blocklist_db(
      new FakeSafeBrowsingDatabaseManager(true));
  ScopedDatabaseManagerForTest scoped_blocklist_db(blocklist_db);

  ExtensionId a = AddExtension("a");
  ExtensionId b = AddExtension("b");
  ExtensionId c = AddExtension("c");

  blocklist_db->Enable();
  blocklist_db->SetUnsafe(a, b);

  // Prepare real fetcher.
  BlocklistStateFetcher* fetcher = new BlocklistStateFetcher(nullptr);
  TestBlocklistStateFetcher fetcher_tester(fetcher);
  blocklist.SetBlocklistStateFetcherForTest(fetcher);

  fetcher_tester.SetBlocklistVerdict(
      a, ClientCRXListInfoResponse_Verdict_CWS_POLICY_VIOLATION);
  fetcher_tester.SetBlocklistVerdict(
      b, ClientCRXListInfoResponse_Verdict_POTENTIALLY_UNWANTED);

  Blocklist::BlocklistStateMap states;
  blocklist.GetBlocklistedIDs(
      {a, b, c},
      base::BindOnce(&Assign<Blocklist::BlocklistStateMap>, &states));
  base::RunLoop().RunUntilIdle();

  // Two fetchers should be created.
  EXPECT_TRUE(fetcher_tester.HandleFetcher(a));
  EXPECT_TRUE(fetcher_tester.HandleFetcher(b));

  EXPECT_EQ(BLOCKLISTED_CWS_POLICY_VIOLATION, states[a]);
  EXPECT_EQ(BLOCKLISTED_POTENTIALLY_UNWANTED, states[b]);
  EXPECT_EQ(0U, states.count(c));

  Blocklist::BlocklistStateMap cached_states;

  blocklist.GetBlocklistedIDs(
      {a, b, c},
      base::BindOnce(&Assign<Blocklist::BlocklistStateMap>, &cached_states));
  base::RunLoop().RunUntilIdle();

  // No new fetchers.
  EXPECT_FALSE(fetcher_tester.HandleFetcher(c));
  EXPECT_EQ(BLOCKLISTED_CWS_POLICY_VIOLATION, cached_states[a]);
  EXPECT_EQ(BLOCKLISTED_POTENTIALLY_UNWANTED, cached_states[b]);
  EXPECT_EQ(0U, cached_states.count(c));
}

}  // namespace extensions
