blob: 5715c5006be29498e2eeb669c861219e26baef58 [file] [log] [blame]
// Copyright 2020 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 "chrome/browser/component_updater/floc_blocklist_component_installer.h"
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/string_util.h"
#include "base/test/bind_test_util.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/version.h"
#include "chrome/test/base/testing_browser_process.h"
#include "components/component_updater/mock_component_updater_service.h"
#include "components/federated_learning/floc_blocklist_service.h"
#include "components/federated_learning/floc_constants.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gmock/include/gmock/gmock-actions.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
namespace component_updater {
namespace {
ACTION_P(QuitMessageLoop, loop) {
loop->Quit();
return true;
}
// This class monitors the OnBlocklistFileReady method calls.
class MockFlocBlocklistService
: public federated_learning::FlocBlocklistService {
public:
MockFlocBlocklistService() = default;
MockFlocBlocklistService(const MockFlocBlocklistService&) = delete;
MockFlocBlocklistService& operator=(const MockFlocBlocklistService&) = delete;
~MockFlocBlocklistService() override = default;
void OnBlocklistFileReady(const base::FilePath& file_path) override {
file_paths_.push_back(file_path);
}
const std::vector<base::FilePath>& file_paths() const { return file_paths_; }
private:
std::vector<base::FilePath> file_paths_;
};
} // namespace
class FlocBlocklistComponentInstallerTest : public PlatformTest {
public:
FlocBlocklistComponentInstallerTest() = default;
FlocBlocklistComponentInstallerTest(
const FlocBlocklistComponentInstallerTest&) = delete;
FlocBlocklistComponentInstallerTest& operator=(
const FlocBlocklistComponentInstallerTest&) = delete;
~FlocBlocklistComponentInstallerTest() override = default;
void SetUp() override {
PlatformTest::SetUp();
ASSERT_TRUE(component_install_dir_.CreateUniqueTempDir());
auto test_floc_blocklist_service =
std::make_unique<MockFlocBlocklistService>();
test_floc_blocklist_service->SetBackgroundTaskRunnerForTesting(
base::SequencedTaskRunnerHandle::Get());
test_floc_blocklist_service_ = test_floc_blocklist_service.get();
TestingBrowserProcess::GetGlobal()->SetFlocBlocklistService(
std::move(test_floc_blocklist_service));
policy_ = std::make_unique<FlocBlocklistComponentInstallerPolicy>(
test_floc_blocklist_service_);
}
void TearDown() override {
TestingBrowserProcess::GetGlobal()->SetFlocBlocklistService(nullptr);
PlatformTest::TearDown();
}
MockFlocBlocklistService* service() { return test_floc_blocklist_service_; }
void WriteStringToFile(const std::string& data, const base::FilePath& path) {
ASSERT_EQ(base::WriteFile(path, data.data(), data.length()),
static_cast<int32_t>(data.length()));
}
base::FilePath component_install_dir() {
return component_install_dir_.GetPath();
}
void CreateTestFlocBlocklist(const std::string& contents) {
base::FilePath file_path =
component_install_dir().Append(federated_learning::kBlocklistFileName);
ASSERT_NO_FATAL_FAILURE(WriteStringToFile(contents, file_path));
}
void LoadFlocBlocklist(const std::string& content_version,
int format_version) {
auto manifest = std::make_unique<base::DictionaryValue>();
manifest->SetInteger(federated_learning::kManifestBlocklistFormatKey,
format_version);
if (!policy_->VerifyInstallation(*manifest, component_install_dir()))
return;
policy_->ComponentReady(base::Version(content_version),
component_install_dir(), std::move(manifest));
}
protected:
content::BrowserTaskEnvironment task_environment_;
base::ScopedTempDir component_install_dir_;
std::unique_ptr<FlocBlocklistComponentInstallerPolicy> policy_;
MockFlocBlocklistService* test_floc_blocklist_service_ = nullptr;
};
TEST_F(FlocBlocklistComponentInstallerTest, TestComponentRegistration) {
auto component_updater =
std::make_unique<component_updater::MockComponentUpdateService>();
base::RunLoop run_loop;
EXPECT_CALL(*component_updater, RegisterComponent(testing::_))
.Times(1)
.WillOnce(QuitMessageLoop(&run_loop));
RegisterFlocBlocklistComponent(component_updater.get(), service());
run_loop.Run();
}
TEST_F(FlocBlocklistComponentInstallerTest, LoadBlocklist) {
ASSERT_TRUE(service());
std::string contents = "abcd";
ASSERT_NO_FATAL_FAILURE(CreateTestFlocBlocklist(contents));
ASSERT_NO_FATAL_FAILURE(LoadFlocBlocklist(
"1.0.0", federated_learning::kCurrentBlocklistFormatVersion));
ASSERT_EQ(service()->file_paths().size(), 1u);
// Assert that the file path is the concatenation of |component_install_dir_|
// and |kBlocklistFileName|, which implies that the |version| argument has no
// impact. In reality, though, the |component_install_dir_| and the |version|
// should always match.
ASSERT_EQ(service()->file_paths()[0].AsUTF8Unsafe(),
component_install_dir()
.Append(federated_learning::kBlocklistFileName)
.AsUTF8Unsafe());
std::string actual_contents;
ASSERT_TRUE(
base::ReadFileToString(service()->file_paths()[0], &actual_contents));
EXPECT_EQ(actual_contents, contents);
}
TEST_F(FlocBlocklistComponentInstallerTest, UnsupportedFormatVersionIgnored) {
ASSERT_TRUE(service());
const std::string contents = "future stuff";
ASSERT_NO_FATAL_FAILURE(CreateTestFlocBlocklist(contents));
ASSERT_NO_FATAL_FAILURE(LoadFlocBlocklist(
"1.0.0", federated_learning::kCurrentBlocklistFormatVersion + 1));
EXPECT_EQ(service()->file_paths().size(), 0u);
}
} // namespace component_updater