#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "chrome/common/extensions/api/enterprise_reporting_private.h"
#include <tuple>
#include "base/command_line.h"
#include "base/environment.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/json/json_writer.h"
#include "base/memory/raw_ptr.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/enterprise/identifiers/profile_id_service_factory.h"
#include "chrome/browser/enterprise/signals/device_info_fetcher.h"
#include "chrome/browser/enterprise/signals/signals_common.h"
#include "chrome/browser/extensions/api/enterprise_reporting_private/chrome_desktop_report_request_helper.h"
#include "chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_api.h"
#include "chrome/browser/extensions/extension_api_unittest.h"
#include "chrome/browser/extensions/test_extension_system.h"
#include "chrome/browser/net/stub_resolver_config_reader.h"
#include "chrome/browser/policy/dm_token_utils.h"
#include "chrome/browser/prefs/browser_prefs.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "components/component_updater/pref_names.h"
#include "components/enterprise/browser/controller/fake_browser_dm_token_storage.h"
#include "components/enterprise/browser/identifiers/profile_id_service.h"
#include "components/enterprise/connectors/core/connectors_prefs.h"
#include "components/policy/core/common/policy_pref_names.h"
#include "components/policy/core/common/policy_types.h"
#include "components/reporting/proto/synced/record.pb.h"
#include "components/safe_browsing/core/common/safe_browsing_prefs.h"
#include "components/version_info/version_info.h"
#include "extensions/browser/api_test_utils.h"
#include "extensions/browser/extension_function_dispatcher.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#if BUILDFLAG(IS_CHROMEOS)
#include "chromeos/dbus/missive/fake_missive_client.h"
#include "chromeos/dbus/missive/missive_client.h"
#include "components/reporting/proto/synced/record_constants.pb.h"
#include "components/reporting/util/status.h"
#endif
#if BUILDFLAG(IS_WIN)
#include <windows.h>
#include <netfw.h>
#include <shlobj.h>
#include <wrl/client.h>
#include "base/test/test_reg_util_win.h"
#endif
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/enterprise/signals/signals_aggregator_factory.h"
#include "components/device_signals/core/browser/mock_signals_aggregator.h"
#include "components/device_signals/core/browser/signals_aggregator.h"
#include "components/device_signals/core/browser/signals_types.h"
#include "components/device_signals/core/browser/user_context.h"
#include "components/device_signals/core/common/common_types.h"
#include "components/device_signals/core/common/signals_constants.h"
#include "components/device_signals/core/common/signals_features.h"
#endif
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#include "base/nix/xdg_util.h"
#endif
enterprise_reporting_private;
SettingValue;
_;
Eq;
Invoke;
IsEmpty;
SizeIs;
StrEq;
WithArgs;
namespace extensions {
std::unique_ptr<KeyedService> CreateProfileIDService(
content::BrowserContext* context) { … }
#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || \
BUILDFLAG(IS_LINUX)
constexpr char kNoError[] = …;
#endif
#if !BUILDFLAG(IS_CHROMEOS)
namespace {
constexpr char kFakeClientId[] = …;
}
class EnterpriseReportingPrivateGetDeviceIdTest : public ExtensionApiUnittest { … };
TEST_F(EnterpriseReportingPrivateGetDeviceIdTest, GetDeviceId) { … }
TEST_F(EnterpriseReportingPrivateGetDeviceIdTest, DeviceIdNotExist) { … }
class EnterpriseReportingPrivateDeviceDataFunctionsTest
: public ExtensionApiUnittest { … };
TEST_F(EnterpriseReportingPrivateDeviceDataFunctionsTest, StoreDeviceData) { … }
TEST_F(EnterpriseReportingPrivateDeviceDataFunctionsTest, DeviceDataMissing) { … }
TEST_F(EnterpriseReportingPrivateDeviceDataFunctionsTest, DeviceBadId) { … }
TEST_F(EnterpriseReportingPrivateDeviceDataFunctionsTest, RetrieveDeviceData) { … }
#if BUILDFLAG(IS_WIN)
class EnterpriseReportingPrivateGetPersistentSecretFunctionTest
: public ExtensionApiUnittest {
public:
EnterpriseReportingPrivateGetPersistentSecretFunctionTest() = default;
EnterpriseReportingPrivateGetPersistentSecretFunctionTest(
const EnterpriseReportingPrivateGetPersistentSecretFunctionTest&) =
delete;
EnterpriseReportingPrivateGetPersistentSecretFunctionTest& operator=(
const EnterpriseReportingPrivateGetPersistentSecretFunctionTest&) =
delete;
void SetUp() override {
ExtensionApiUnittest::SetUp();
#if BUILDFLAG(IS_WIN)
ASSERT_NO_FATAL_FAILURE(
registry_override_manager_.OverrideRegistry(HKEY_CURRENT_USER));
#endif
}
private:
#if BUILDFLAG(IS_WIN)
registry_util::RegistryOverrideManager registry_override_manager_;
#endif
};
TEST_F(EnterpriseReportingPrivateGetPersistentSecretFunctionTest, GetSecret) {
auto function = base::MakeRefCounted<
EnterpriseReportingPrivateGetPersistentSecretFunction>();
std::optional<base::Value> result1 =
RunFunctionAndReturnValue(function.get(), "[]");
ASSERT_TRUE(result1);
ASSERT_TRUE(result1->is_blob());
auto generated_blob = result1->GetBlob();
auto function2 = base::MakeRefCounted<
EnterpriseReportingPrivateGetPersistentSecretFunction>();
std::optional<base::Value> result2 =
RunFunctionAndReturnValue(function2.get(), "[]");
ASSERT_TRUE(result2);
ASSERT_TRUE(result2->is_blob());
ASSERT_EQ(generated_blob, result2->GetBlob());
auto function3 = base::MakeRefCounted<
EnterpriseReportingPrivateGetPersistentSecretFunction>();
std::optional<base::Value> result3 =
RunFunctionAndReturnValue(function3.get(), "[true]");
ASSERT_TRUE(result3);
ASSERT_TRUE(result3->is_blob());
ASSERT_EQ(generated_blob, result3->GetBlob());
const wchar_t kDefaultRegistryPath[] =
L"SOFTWARE\\Google\\Endpoint Verification";
const wchar_t kValueName[] = L"Safe Storage";
base::win::RegKey key;
ASSERT_EQ(ERROR_SUCCESS,
key.Create(HKEY_CURRENT_USER, kDefaultRegistryPath, KEY_WRITE));
ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(kValueName, 1337));
auto function4 = base::MakeRefCounted<
EnterpriseReportingPrivateGetPersistentSecretFunction>();
std::string error = RunFunctionAndReturnError(function4.get(), "[]");
ASSERT_FALSE(error.empty());
auto function5 = base::MakeRefCounted<
EnterpriseReportingPrivateGetPersistentSecretFunction>();
std::optional<base::Value> result5 =
RunFunctionAndReturnValue(function5.get(), "[true]");
ASSERT_TRUE(result5);
ASSERT_TRUE(result5->is_blob());
ASSERT_NE(generated_blob, result5->GetBlob());
}
#endif
EnterpriseReportingPrivateGetDeviceInfoTest;
TEST_F(EnterpriseReportingPrivateGetDeviceInfoTest, GetDeviceInfo) { … }
TEST_F(EnterpriseReportingPrivateGetDeviceInfoTest, GetDeviceInfoConversion) { … }
#endif
class EnterpriseReportingPrivateGetContextInfoTest
: public ExtensionApiUnittest { … };
TEST_F(EnterpriseReportingPrivateGetContextInfoTest, NoSpecialContext) { … }
#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
class EnterpriseReportingPrivateGetContextInfoThirdPartyBlockingTest
: public EnterpriseReportingPrivateGetContextInfoTest,
public testing::WithParamInterface<bool> {};
TEST_P(EnterpriseReportingPrivateGetContextInfoThirdPartyBlockingTest, Test) {
bool policyValue = GetParam();
g_browser_process->local_state()->SetBoolean(
prefs::kThirdPartyBlockingEnabled, policyValue);
enterprise_reporting_private::ContextInfo info = GetContextInfo();
EXPECT_TRUE(info.browser_affiliation_ids.empty());
EXPECT_TRUE(info.profile_affiliation_ids.empty());
EXPECT_TRUE(info.on_file_attached_providers.empty());
EXPECT_TRUE(info.on_file_downloaded_providers.empty());
EXPECT_TRUE(info.on_bulk_data_entry_providers.empty());
EXPECT_EQ(enterprise_reporting_private::RealtimeUrlCheckMode::kDisabled,
info.realtime_url_check_mode);
EXPECT_TRUE(info.on_security_event_providers.empty());
EXPECT_EQ(version_info::GetVersionNumber(), info.browser_version);
EXPECT_EQ(enterprise_reporting_private::SafeBrowsingLevel::kStandard,
info.safe_browsing_protection_level);
EXPECT_EQ(BuiltInDnsClientPlatformDefault(),
info.built_in_dns_client_enabled);
EXPECT_FALSE(info.chrome_remote_desktop_app_blocked);
EXPECT_EQ(policyValue, *info.third_party_blocking_enabled);
}
INSTANTIATE_TEST_SUITE_P(
,
EnterpriseReportingPrivateGetContextInfoThirdPartyBlockingTest,
testing::Bool());
#endif
class EnterpriseReportingPrivateGetContextInfoSafeBrowsingTest
: public EnterpriseReportingPrivateGetContextInfoTest,
public testing::WithParamInterface<std::tuple<bool, bool>> { … };
TEST_P(EnterpriseReportingPrivateGetContextInfoSafeBrowsingTest, Test) { … }
INSTANTIATE_TEST_SUITE_P(…);
class EnterpriseReportingPrivateGetContextInfoBuiltInDnsClientTest
: public EnterpriseReportingPrivateGetContextInfoTest,
public testing::WithParamInterface<bool> { … };
TEST_P(EnterpriseReportingPrivateGetContextInfoBuiltInDnsClientTest, Test) { … }
INSTANTIATE_TEST_SUITE_P(…);
class EnterpriseReportingPrivateGetContextPasswordProtectionWarningTrigger
: public EnterpriseReportingPrivateGetContextInfoTest,
public testing::WithParamInterface<
enterprise_reporting_private::PasswordProtectionTrigger> { … };
TEST_P(EnterpriseReportingPrivateGetContextPasswordProtectionWarningTrigger,
Test) { … }
INSTANTIATE_TEST_SUITE_P(…);
#if BUILDFLAG(IS_LINUX)
class EnterpriseReportingPrivateGetContextOSFirewallLinuxTest
: public EnterpriseReportingPrivateGetContextInfoTest,
public testing::WithParamInterface<
enterprise_reporting_private::SettingValue> { … };
TEST_F(EnterpriseReportingPrivateGetContextOSFirewallLinuxTest,
NoFirewallFile) { … }
TEST_F(EnterpriseReportingPrivateGetContextOSFirewallLinuxTest, NoEnabledKey) { … }
TEST_P(EnterpriseReportingPrivateGetContextOSFirewallLinuxTest, Test) { … }
INSTANTIATE_TEST_SUITE_P(…);
#endif
class EnterpriseReportingPrivateGetContextInfoChromeRemoteDesktopAppBlockedTest
: public EnterpriseReportingPrivateGetContextInfoTest,
public testing::WithParamInterface<const char*> { … };
TEST_P(
EnterpriseReportingPrivateGetContextInfoChromeRemoteDesktopAppBlockedTest,
BlockedURL) { … }
TEST_P(
EnterpriseReportingPrivateGetContextInfoChromeRemoteDesktopAppBlockedTest,
AllowedURL) { … }
TEST_P(
EnterpriseReportingPrivateGetContextInfoChromeRemoteDesktopAppBlockedTest,
BlockedAndAllowedURL) { … }
INSTANTIATE_TEST_SUITE_P(…);
#if BUILDFLAG(IS_WIN)
class EnterpriseReportingPrivateGetContextInfoOSFirewallTest
: public EnterpriseReportingPrivateGetContextInfoTest,
public testing::WithParamInterface<SettingValue> {
public:
EnterpriseReportingPrivateGetContextInfoOSFirewallTest()
: enabled_(VARIANT_TRUE) {}
protected:
void SetUp() override {
if (!::IsUserAnAdmin()) {
GTEST_SKIP() << "This test must be run by an admin user";
}
EnterpriseReportingPrivateGetContextInfoTest::SetUp();
HRESULT hr = CoCreateInstance(CLSID_NetFwPolicy2, nullptr, CLSCTX_ALL,
IID_PPV_ARGS(&firewall_policy_));
EXPECT_GE(hr, 0);
long profile_types = 0;
hr = firewall_policy_->get_CurrentProfileTypes(&profile_types);
EXPECT_GE(hr, 0);
const NET_FW_PROFILE_TYPE2 kProfileTypes[] = {NET_FW_PROFILE2_PUBLIC,
NET_FW_PROFILE2_PRIVATE,
NET_FW_PROFILE2_DOMAIN};
for (size_t i = 0; i < std::size(kProfileTypes); ++i) {
if ((profile_types & kProfileTypes[i]) != 0) {
hr = firewall_policy_->get_FirewallEnabled(kProfileTypes[i], &enabled_);
EXPECT_GE(hr, 0);
active_profile_ = kProfileTypes[i];
hr = firewall_policy_->put_FirewallEnabled(
kProfileTypes[i], firewall_value_ == SettingValue::ENABLED
? VARIANT_TRUE
: VARIANT_FALSE);
EXPECT_GE(hr, 0);
break;
}
}
}
void TearDown() override {
if (!::IsUserAnAdmin()) {
return;
}
HRESULT hr =
firewall_policy_->put_FirewallEnabled(active_profile_, enabled_);
EXPECT_GE(hr, 0);
EnterpriseReportingPrivateGetContextInfoTest::TearDown();
}
extensions::api::enterprise_reporting_private::SettingValue
ToInfoSettingValue(enterprise_signals::SettingValue value) {
switch (value) {
case SettingValue::DISABLED:
return extensions::api::enterprise_reporting_private::SettingValue::
kDisabled;
case SettingValue::ENABLED:
return extensions::api::enterprise_reporting_private::SettingValue::
kEnabled;
default:
NOTREACHED_IN_MIGRATION();
return extensions::api::enterprise_reporting_private::SettingValue::
kUnknown;
}
}
Microsoft::WRL::ComPtr<INetFwPolicy2> firewall_policy_;
SettingValue firewall_value_ = GetParam();
VARIANT_BOOL enabled_;
NET_FW_PROFILE_TYPE2 active_profile_;
};
TEST_P(EnterpriseReportingPrivateGetContextInfoOSFirewallTest, Test) {
enterprise_reporting_private::ContextInfo info = GetContextInfo();
EXPECT_TRUE(info.browser_affiliation_ids.empty());
EXPECT_TRUE(info.profile_affiliation_ids.empty());
EXPECT_TRUE(info.on_file_attached_providers.empty());
EXPECT_TRUE(info.on_file_downloaded_providers.empty());
EXPECT_TRUE(info.on_bulk_data_entry_providers.empty());
EXPECT_EQ(enterprise_reporting_private::RealtimeUrlCheckMode::kDisabled,
info.realtime_url_check_mode);
EXPECT_TRUE(info.on_security_event_providers.empty());
EXPECT_EQ(version_info::GetVersionNumber(), info.browser_version);
EXPECT_EQ(enterprise_reporting_private::SafeBrowsingLevel::kStandard,
info.safe_browsing_protection_level);
EXPECT_EQ(BuiltInDnsClientPlatformDefault(),
info.built_in_dns_client_enabled);
EXPECT_EQ(
enterprise_reporting_private::PasswordProtectionTrigger::kPolicyUnset,
info.password_protection_warning_trigger);
EXPECT_FALSE(info.chrome_remote_desktop_app_blocked);
ExpectDefaultThirdPartyBlockingEnabled(info);
EXPECT_EQ(ToInfoSettingValue(firewall_value_), info.os_firewall);
EXPECT_TRUE(info.enterprise_profile_id);
}
INSTANTIATE_TEST_SUITE_P(,
EnterpriseReportingPrivateGetContextInfoOSFirewallTest,
testing::Values(SettingValue::DISABLED,
SettingValue::ENABLED));
#endif
class EnterpriseReportingPrivateGetContextInfoRealTimeURLCheckTest
: public EnterpriseReportingPrivateGetContextInfoTest,
public testing::WithParamInterface<bool> { … };
INSTANTIATE_TEST_SUITE_P(…);
TEST_P(EnterpriseReportingPrivateGetContextInfoRealTimeURLCheckTest, Test) { … }
#if BUILDFLAG(IS_CHROMEOS)
class EnterpriseReportingPrivateEnqueueRecordFunctionTest
: public ExtensionApiUnittest {
protected:
static constexpr char kTestDMTokenValue[] = "test_dm_token_value";
EnterpriseReportingPrivateEnqueueRecordFunctionTest() = default;
void SetUp() override {
ExtensionApiUnittest::SetUp();
::chromeos::MissiveClient::InitializeFake();
function_ =
base::MakeRefCounted<EnterpriseReportingPrivateEnqueueRecordFunction>();
const auto record = GetTestRecord();
serialized_record_data_.resize(record.ByteSizeLong());
ASSERT_TRUE(record.SerializeToArray(serialized_record_data_.data(),
serialized_record_data_.size()));
}
void TearDown() override {
function_.reset();
::chromeos::MissiveClient::Shutdown();
ExtensionApiUnittest::TearDown();
}
::reporting::Record GetTestRecord() const {
base::Value::Dict data;
data.Set("TEST_KEY", base::Value("TEST_VALUE"));
std::string serialized_data;
DCHECK(base::JSONWriter::Write(data, &serialized_data));
::reporting::Record record;
record.set_data(serialized_data);
record.set_destination(::reporting::Destination::TELEMETRY_METRIC);
record.set_timestamp_us(base::Time::Now().InMillisecondsSinceUnixEpoch() *
base::Time::kMicrosecondsPerMillisecond);
return record;
}
void VerifyNoRecordsEnqueued(::reporting::Priority priority =
::reporting::Priority::BACKGROUND_BATCH) {
::chromeos::MissiveClient::TestInterface* const missive_test_interface =
::chromeos::MissiveClient::Get()->GetTestInterface();
ASSERT_TRUE(missive_test_interface);
const std::vector<::reporting::Record>& records =
missive_test_interface->GetEnqueuedRecords(priority);
ASSERT_THAT(records, IsEmpty());
}
std::vector<uint8_t> serialized_record_data_;
scoped_refptr<extensions::EnterpriseReportingPrivateEnqueueRecordFunction>
function_;
};
TEST_F(EnterpriseReportingPrivateEnqueueRecordFunctionTest,
ValidRecordSuccessfullyEnqueued) {
function_->SetProfileIsAffiliatedForTesting(true);
api::enterprise_reporting_private::EnqueueRecordRequest
enqueue_record_request;
enqueue_record_request.record_data = serialized_record_data_;
enqueue_record_request.priority = ::reporting::Priority::BACKGROUND_BATCH;
enqueue_record_request.event_type =
api::enterprise_reporting_private::EventType::kUser;
base::Value::List params;
params.Append(enqueue_record_request.ToValue());
const auto dm_token = policy::DMToken::CreateValidToken(kTestDMTokenValue);
policy::SetDMTokenForTesting(dm_token);
api_test_utils::RunFunction(
function_.get(), std::move(params),
std::make_unique<ExtensionFunctionDispatcher>(profile()),
extensions::api_test_utils::FunctionMode::kNone);
EXPECT_EQ(function_->GetError(), kNoError);
::chromeos::MissiveClient::TestInterface* const missive_test_interface =
::chromeos::MissiveClient::Get()->GetTestInterface();
ASSERT_TRUE(missive_test_interface);
const std::vector<::reporting::Record>& background_batch_records =
missive_test_interface->GetEnqueuedRecords(
::reporting::Priority::BACKGROUND_BATCH);
ASSERT_THAT(background_batch_records, SizeIs(1));
EXPECT_THAT(background_batch_records[0].destination(),
Eq(::reporting::Destination::TELEMETRY_METRIC));
EXPECT_THAT(background_batch_records[0].dm_token(), StrEq(dm_token.value()));
EXPECT_THAT(background_batch_records[0].data(),
StrEq(GetTestRecord().data()));
}
TEST_F(EnterpriseReportingPrivateEnqueueRecordFunctionTest,
InvalidPriorityReturnsError) {
function_->SetProfileIsAffiliatedForTesting(true);
api::enterprise_reporting_private::EnqueueRecordRequest
enqueue_record_request;
enqueue_record_request.record_data = serialized_record_data_;
enqueue_record_request.priority = -1;
enqueue_record_request.event_type =
api::enterprise_reporting_private::EventType::kUser;
base::Value::List params;
params.Append(enqueue_record_request.ToValue());
policy::SetDMTokenForTesting(
policy::DMToken::CreateValidToken(kTestDMTokenValue));
api_test_utils::RunFunction(
function_.get(), std::move(params),
std::make_unique<ExtensionFunctionDispatcher>(profile()),
extensions::api_test_utils::FunctionMode::kNone);
EXPECT_EQ(function_->GetError(),
EnterpriseReportingPrivateEnqueueRecordFunction::
kErrorInvalidEnqueueRecordRequest);
VerifyNoRecordsEnqueued();
}
TEST_F(EnterpriseReportingPrivateEnqueueRecordFunctionTest,
NonAffiliatedUserReturnsError) {
function_->SetProfileIsAffiliatedForTesting(false);
api::enterprise_reporting_private::EnqueueRecordRequest
enqueue_record_request;
enqueue_record_request.record_data = serialized_record_data_;
enqueue_record_request.priority = ::reporting::Priority::BACKGROUND_BATCH;
enqueue_record_request.event_type =
api::enterprise_reporting_private::EventType::kUser;
base::Value::List params;
params.Append(enqueue_record_request.ToValue());
policy::SetDMTokenForTesting(
policy::DMToken::CreateValidToken(kTestDMTokenValue));
api_test_utils::RunFunction(
function_.get(), std::move(params),
std::make_unique<ExtensionFunctionDispatcher>(profile()),
extensions::api_test_utils::FunctionMode::kNone);
EXPECT_EQ(function_->GetError(),
EnterpriseReportingPrivateEnqueueRecordFunction::
kErrorProfileNotAffiliated);
VerifyNoRecordsEnqueued();
}
TEST_F(EnterpriseReportingPrivateEnqueueRecordFunctionTest,
InvalidDMTokenReturnsError) {
function_->SetProfileIsAffiliatedForTesting(true);
api::enterprise_reporting_private::EnqueueRecordRequest
enqueue_record_request;
enqueue_record_request.record_data = serialized_record_data_;
enqueue_record_request.priority = ::reporting::Priority::BACKGROUND_BATCH;
enqueue_record_request.event_type =
api::enterprise_reporting_private::EventType::kUser;
base::Value::List params;
params.Append(enqueue_record_request.ToValue());
policy::SetDMTokenForTesting(policy::DMToken::CreateInvalidToken());
api_test_utils::RunFunction(
function_.get(), std::move(params),
std::make_unique<ExtensionFunctionDispatcher>(profile()),
extensions::api_test_utils::FunctionMode::kNone);
EXPECT_EQ(function_->GetError(),
EnterpriseReportingPrivateEnqueueRecordFunction::
kErrorCannotAssociateRecordWithUser);
VerifyNoRecordsEnqueued();
}
TEST_F(EnterpriseReportingPrivateEnqueueRecordFunctionTest,
InvalidRecordWithMissingTimestampReturnsError) {
function_->SetProfileIsAffiliatedForTesting(true);
api::enterprise_reporting_private::EnqueueRecordRequest
enqueue_record_request;
auto record = GetTestRecord();
record.clear_timestamp_us();
serialized_record_data_.clear();
serialized_record_data_.resize(record.ByteSizeLong());
ASSERT_TRUE(record.SerializeToArray(serialized_record_data_.data(),
serialized_record_data_.size()));
enqueue_record_request.record_data = serialized_record_data_;
enqueue_record_request.priority = ::reporting::Priority::BACKGROUND_BATCH;
enqueue_record_request.event_type =
api::enterprise_reporting_private::EventType::kUser;
base::Value::List params;
params.Append(enqueue_record_request.ToValue());
policy::SetDMTokenForTesting(
policy::DMToken::CreateValidToken(kTestDMTokenValue));
api_test_utils::RunFunction(
function_.get(), std::move(params),
std::make_unique<ExtensionFunctionDispatcher>(profile()),
extensions::api_test_utils::FunctionMode::kNone);
EXPECT_EQ(function_->GetError(),
EnterpriseReportingPrivateEnqueueRecordFunction::
kErrorInvalidEnqueueRecordRequest);
VerifyNoRecordsEnqueued();
}
#endif
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
namespace {
constexpr char kFakeUserId[] = …;
enterprise_reporting_private::UserContext GetFakeUserContext() { … }
std::unique_ptr<KeyedService> BuildMockAggregator(
content::BrowserContext* context) { … }
}
class UserContextGatedTest : public ExtensionApiUnittest { … };
class EnterpriseReportingPrivateGetFileSystemInfoTest
: public UserContextGatedTest { … };
TEST_F(EnterpriseReportingPrivateGetFileSystemInfoTest, Success) { … }
TEST_F(EnterpriseReportingPrivateGetFileSystemInfoTest, TopLevelError) { … }
TEST_F(EnterpriseReportingPrivateGetFileSystemInfoTest, CollectionError) { … }
class EnterpriseReportingPrivateGetFileSystemInfoDisabledTest
: public EnterpriseReportingPrivateGetFileSystemInfoTest { … };
TEST_F(EnterpriseReportingPrivateGetFileSystemInfoDisabledTest,
FlagDisabled_Test) { … }
#endif
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
class EnterpriseReportingPrivateGetSettingsTest : public UserContextGatedTest {
protected:
void SetUp() override {
UserContextGatedTest::SetUp();
SetFeatureFlag();
function_ =
base::MakeRefCounted<EnterpriseReportingPrivateGetSettingsFunction>();
}
device_signals::SignalName signal_name() {
return device_signals::SignalName::kSystemSettings;
}
enterprise_reporting_private::GetSettingsOptions GetFakeSettingsOptionsParam()
const {
enterprise_reporting_private::GetSettingsOptions api_param;
api_param.path = "some path";
api_param.key = "some key";
api_param.get_value = true;
api_param.hive =
enterprise_reporting_private::RegistryHive::kHkeyCurrentUser;
return api_param;
}
std::string GetFakeRequest() const {
enterprise_reporting_private::GetSettingsRequest request;
request.user_context = GetFakeUserContext();
request.options.push_back(GetFakeSettingsOptionsParam());
base::Value::List params;
params.Append(request.ToValue());
std::string json_value;
base::JSONWriter::Write(params, &json_value);
return json_value;
}
scoped_refptr<extensions::EnterpriseReportingPrivateGetSettingsFunction>
function_;
};
TEST_F(EnterpriseReportingPrivateGetSettingsTest, Success) {
device_signals::SettingsItem fake_settings_item;
fake_settings_item.path = "fake path";
fake_settings_item.key = "fake key";
fake_settings_item.presence = device_signals::PresenceValue::kFound;
std::string setting_json_value = "123";
fake_settings_item.setting_json_value = setting_json_value;
fake_settings_item.hive = device_signals::RegistryHive::kHkeyCurrentUser;
device_signals::SettingsResponse signal_response;
signal_response.settings_items.push_back(fake_settings_item);
device_signals::SignalsAggregationResponse expected_response;
expected_response.settings_response = signal_response;
SetFakeResponse(expected_response);
auto response = api_test_utils::RunFunctionAndReturnSingleResult(
function_.get(), GetFakeRequest(), profile());
EXPECT_EQ(function_->GetError(), kNoError);
ASSERT_TRUE(response);
ASSERT_TRUE(response->is_list());
const base::Value::List& list_value = response->GetList();
ASSERT_EQ(list_value.size(), signal_response.settings_items.size());
const base::Value& settings_value = list_value.front();
ASSERT_TRUE(settings_value.is_dict());
auto parsed_settings_signal =
enterprise_reporting_private::GetSettingsResponse::FromValue(
settings_value.GetDict());
ASSERT_TRUE(parsed_settings_signal);
EXPECT_EQ(parsed_settings_signal->path, fake_settings_item.path);
EXPECT_EQ(parsed_settings_signal->presence,
enterprise_reporting_private::PresenceValue::kFound);
ASSERT_TRUE(parsed_settings_signal->value);
EXPECT_EQ(parsed_settings_signal->value.value(), setting_json_value);
ASSERT_NE(parsed_settings_signal->hive,
enterprise_reporting_private::RegistryHive::kNone);
EXPECT_EQ(parsed_settings_signal->hive,
enterprise_reporting_private::RegistryHive::kHkeyCurrentUser);
histogram_tester_.ExpectUniqueSample(
"Enterprise.DeviceSignals.Collection.Request.SystemSettings.Items", 1, 1);
histogram_tester_.ExpectUniqueSample(
"Enterprise.DeviceSignals.Collection.SystemSettings.Delta", 0, 1);
histogram_tester_.ExpectUniqueSample(
"Enterprise.DeviceSignals.Collection.Success", signal_name(), 1);
histogram_tester_.ExpectUniqueSample(
"Enterprise.DeviceSignals.Collection.Success.SystemSettings.Items",
1,
1);
histogram_tester_.ExpectTotalCount(
"Enterprise.DeviceSignals.Collection.Success.SystemSettings.Latency", 1);
histogram_tester_.ExpectTotalCount(
"Enterprise.DeviceSignals.Collection.Failure", 0);
histogram_tester_.ExpectTotalCount(
"Enterprise.DeviceSignals.Collection.Failure.SystemSettings.Latency", 0);
}
TEST_F(EnterpriseReportingPrivateGetSettingsTest, TopLevelError) {
device_signals::SignalCollectionError expected_error =
device_signals::SignalCollectionError::kConsentRequired;
device_signals::SignalsAggregationResponse expected_response;
expected_response.top_level_error = expected_error;
SetFakeResponse(expected_response);
auto error = api_test_utils::RunFunctionAndReturnError(
function_.get(), GetFakeRequest(), profile());
EXPECT_EQ(error, function_->GetError());
EXPECT_EQ(error, device_signals::ErrorToString(expected_error));
histogram_tester_.ExpectUniqueSample(
"Enterprise.DeviceSignals.Collection.Request.SystemSettings.Items", 1, 1);
histogram_tester_.ExpectUniqueSample(
"Enterprise.DeviceSignals.Collection.Failure", signal_name(), 1);
histogram_tester_.ExpectUniqueSample(
"Enterprise.DeviceSignals.Collection.Failure.SystemSettings."
"TopLevelError",
expected_error,
1);
histogram_tester_.ExpectTotalCount(
"Enterprise.DeviceSignals.Collection.Failure.SystemSettings.Latency", 1);
histogram_tester_.ExpectTotalCount(
"Enterprise.DeviceSignals.Collection.Success", 0);
histogram_tester_.ExpectTotalCount(
"Enterprise.DeviceSignals.Collection.Success.SystemSettings.Latency", 0);
histogram_tester_.ExpectTotalCount(
"Enterprise.DeviceSignals.Collection.SystemSettings.Delta", 0);
}
TEST_F(EnterpriseReportingPrivateGetSettingsTest, CollectionError) {
device_signals::SignalCollectionError expected_error =
device_signals::SignalCollectionError::kMissingSystemService;
device_signals::SettingsResponse signal_response;
signal_response.collection_error = expected_error;
device_signals::SignalsAggregationResponse expected_response;
expected_response.settings_response = signal_response;
SetFakeResponse(expected_response);
auto error = api_test_utils::RunFunctionAndReturnError(
function_.get(), GetFakeRequest(), profile());
EXPECT_EQ(error, function_->GetError());
EXPECT_EQ(error, device_signals::ErrorToString(expected_error));
histogram_tester_.ExpectUniqueSample(
"Enterprise.DeviceSignals.Collection.Request.SystemSettings.Items", 1, 1);
histogram_tester_.ExpectUniqueSample(
"Enterprise.DeviceSignals.Collection.Failure", signal_name(), 1);
histogram_tester_.ExpectUniqueSample(
"Enterprise.DeviceSignals.Collection.Failure.SystemSettings."
"CollectionLevelError",
expected_error,
1);
histogram_tester_.ExpectTotalCount(
"Enterprise.DeviceSignals.Collection.Failure.SystemSettings.Latency", 1);
histogram_tester_.ExpectTotalCount(
"Enterprise.DeviceSignals.Collection.Success", 0);
histogram_tester_.ExpectTotalCount(
"Enterprise.DeviceSignals.Collection.Success.SystemSettings.Latency", 0);
histogram_tester_.ExpectTotalCount(
"Enterprise.DeviceSignals.Collection.SystemSettings.Delta", 0);
}
class EnterpriseReportingPrivateGetSettingsDisabledTest
: public EnterpriseReportingPrivateGetSettingsTest {
protected:
void SetFeatureFlag() override {
scoped_features_.InitAndEnableFeatureWithParameters(
enterprise_signals::features::kNewEvSignalsEnabled,
{{"DisableSettings", "true"}});
}
};
TEST_F(EnterpriseReportingPrivateGetSettingsDisabledTest, FlagDisabled_Test) {
auto error = api_test_utils::RunFunctionAndReturnError(
function_.get(), GetFakeRequest(), profile());
EXPECT_EQ(error, function_->GetError());
EXPECT_EQ(error, device_signals::ErrorToString(
device_signals::SignalCollectionError::kUnsupported));
}
#endif
#if BUILDFLAG(IS_WIN)
std::string GetFakeUserContextJsonParams() {
auto user_context = GetFakeUserContext();
base::Value::List params;
params.Append(user_context.ToValue());
std::string json_value;
base::JSONWriter::Write(params, &json_value);
return json_value;
}
class EnterpriseReportingPrivateGetAvInfoTest : public UserContextGatedTest {
protected:
void SetUp() override {
UserContextGatedTest::SetUp();
SetFeatureFlag();
function_ =
base::MakeRefCounted<EnterpriseReportingPrivateGetAvInfoFunction>();
}
device_signals::SignalName signal_name() {
return device_signals::SignalName::kAntiVirus;
}
scoped_refptr<extensions::EnterpriseReportingPrivateGetAvInfoFunction>
function_;
};
TEST_F(EnterpriseReportingPrivateGetAvInfoTest, Success) {
device_signals::AvProduct fake_av_product;
fake_av_product.display_name = "Fake display name";
fake_av_product.state = device_signals::AvProductState::kOff;
fake_av_product.product_id = "fake product id";
device_signals::AntiVirusSignalResponse av_response;
av_response.av_products.push_back(fake_av_product);
device_signals::SignalsAggregationResponse expected_response;
expected_response.av_signal_response = av_response;
SetFakeResponse(expected_response);
auto response = api_test_utils::RunFunctionAndReturnSingleResult(
function_.get(), GetFakeUserContextJsonParams(), profile());
EXPECT_EQ(function_->GetError(), kNoError);
ASSERT_TRUE(response);
ASSERT_TRUE(response->is_list());
const base::Value::List& list_value = response->GetList();
ASSERT_EQ(list_value.size(), av_response.av_products.size());
const base::Value& av_value = list_value.front();
ASSERT_TRUE(av_value.is_dict());
auto parsed_av_signal =
enterprise_reporting_private::AntiVirusSignal::FromValue(
av_value.GetDict());
ASSERT_TRUE(parsed_av_signal);
EXPECT_EQ(parsed_av_signal->display_name, fake_av_product.display_name);
EXPECT_EQ(parsed_av_signal->state,
enterprise_reporting_private::AntiVirusProductState::kOff);
EXPECT_EQ(parsed_av_signal->product_id, fake_av_product.product_id);
histogram_tester_.ExpectUniqueSample(
"Enterprise.DeviceSignals.Collection.Success", signal_name(), 1);
histogram_tester_.ExpectUniqueSample(
"Enterprise.DeviceSignals.Collection.Success.AntiVirus.Items",
1,
1);
histogram_tester_.ExpectTotalCount(
"Enterprise.DeviceSignals.Collection.Success.AntiVirus.Latency", 1);
histogram_tester_.ExpectTotalCount(
"Enterprise.DeviceSignals.Collection.Failure", 0);
histogram_tester_.ExpectTotalCount(
"Enterprise.DeviceSignals.Collection.Failure.AntiVirus.Latency", 0);
}
TEST_F(EnterpriseReportingPrivateGetAvInfoTest, TopLevelError) {
device_signals::SignalCollectionError expected_error =
device_signals::SignalCollectionError::kConsentRequired;
device_signals::SignalsAggregationResponse expected_response;
expected_response.top_level_error = expected_error;
SetFakeResponse(expected_response);
auto error = api_test_utils::RunFunctionAndReturnError(
function_.get(), GetFakeUserContextJsonParams(), profile());
EXPECT_EQ(error, function_->GetError());
EXPECT_EQ(error, device_signals::ErrorToString(expected_error));
histogram_tester_.ExpectUniqueSample(
"Enterprise.DeviceSignals.Collection.Failure", signal_name(), 1);
histogram_tester_.ExpectUniqueSample(
"Enterprise.DeviceSignals.Collection.Failure.AntiVirus.TopLevelError",
expected_error,
1);
histogram_tester_.ExpectTotalCount(
"Enterprise.DeviceSignals.Collection.Failure.AntiVirus.Latency", 1);
histogram_tester_.ExpectTotalCount(
"Enterprise.DeviceSignals.Collection.Success", 0);
histogram_tester_.ExpectTotalCount(
"Enterprise.DeviceSignals.Collection.Success.AntiVirus.Latency", 0);
}
TEST_F(EnterpriseReportingPrivateGetAvInfoTest, CollectionError) {
device_signals::SignalCollectionError expected_error =
device_signals::SignalCollectionError::kMissingSystemService;
device_signals::AntiVirusSignalResponse av_response;
av_response.collection_error = expected_error;
device_signals::SignalsAggregationResponse expected_response;
expected_response.av_signal_response = av_response;
SetFakeResponse(expected_response);
auto error = api_test_utils::RunFunctionAndReturnError(
function_.get(), GetFakeUserContextJsonParams(), profile());
EXPECT_EQ(error, function_->GetError());
EXPECT_EQ(error, device_signals::ErrorToString(expected_error));
histogram_tester_.ExpectUniqueSample(
"Enterprise.DeviceSignals.Collection.Failure", signal_name(), 1);
histogram_tester_.ExpectUniqueSample(
"Enterprise.DeviceSignals.Collection.Failure.AntiVirus."
"CollectionLevelError",
expected_error,
1);
histogram_tester_.ExpectTotalCount(
"Enterprise.DeviceSignals.Collection.Failure.AntiVirus.Latency", 1);
histogram_tester_.ExpectTotalCount(
"Enterprise.DeviceSignals.Collection.Success", 0);
histogram_tester_.ExpectTotalCount(
"Enterprise.DeviceSignals.Collection.Success.AntiVirus.Latency", 0);
}
class EnterpriseReportingPrivateGetAvInfoDisabledTest
: public EnterpriseReportingPrivateGetAvInfoTest {
protected:
void SetFeatureFlag() override {
scoped_features_.InitAndEnableFeatureWithParameters(
enterprise_signals::features::kNewEvSignalsEnabled,
{{"DisableAntiVirus", "true"}});
}
};
TEST_F(EnterpriseReportingPrivateGetAvInfoDisabledTest, FlagDisabled_Test) {
auto error = api_test_utils::RunFunctionAndReturnError(
function_.get(), GetFakeUserContextJsonParams(), profile());
EXPECT_EQ(error, function_->GetError());
EXPECT_EQ(error, device_signals::ErrorToString(
device_signals::SignalCollectionError::kUnsupported));
}
class EnterpriseReportingPrivateGetHotfixesTest : public UserContextGatedTest {
protected:
void SetUp() override {
UserContextGatedTest::SetUp();
SetFeatureFlag();
function_ =
base::MakeRefCounted<EnterpriseReportingPrivateGetHotfixesFunction>();
}
device_signals::SignalName signal_name() {
return device_signals::SignalName::kHotfixes;
}
scoped_refptr<extensions::EnterpriseReportingPrivateGetHotfixesFunction>
function_;
};
TEST_F(EnterpriseReportingPrivateGetHotfixesTest, Success) {
static constexpr char kFakeHotfixId[] = "hotfix id";
device_signals::HotfixSignalResponse hotfix_response;
hotfix_response.hotfixes.push_back({kFakeHotfixId});
device_signals::SignalsAggregationResponse expected_response;
expected_response.hotfix_signal_response = hotfix_response;
SetFakeResponse(expected_response);
auto response = api_test_utils::RunFunctionAndReturnSingleResult(
function_.get(), GetFakeUserContextJsonParams(), profile());
EXPECT_EQ(function_->GetError(), kNoError);
ASSERT_TRUE(response);
ASSERT_TRUE(response->is_list());
const base::Value::List& list_value = response->GetList();
ASSERT_EQ(list_value.size(), hotfix_response.hotfixes.size());
const base::Value& hotfix_value = list_value.front();
ASSERT_TRUE(hotfix_value.is_dict());
auto parsed_hotfix = enterprise_reporting_private::HotfixSignal::FromValue(
hotfix_value.GetDict());
ASSERT_TRUE(parsed_hotfix);
EXPECT_EQ(parsed_hotfix->hotfix_id, kFakeHotfixId);
histogram_tester_.ExpectUniqueSample(
"Enterprise.DeviceSignals.Collection.Success", signal_name(), 1);
histogram_tester_.ExpectUniqueSample(
"Enterprise.DeviceSignals.Collection.Success.Hotfixes.Items",
1,
1);
histogram_tester_.ExpectTotalCount(
"Enterprise.DeviceSignals.Collection.Success.Hotfixes.Latency", 1);
histogram_tester_.ExpectTotalCount(
"Enterprise.DeviceSignals.Collection.Failure", 0);
histogram_tester_.ExpectTotalCount(
"Enterprise.DeviceSignals.Collection.Failure.Hotfixes.Latency", 0);
}
TEST_F(EnterpriseReportingPrivateGetHotfixesTest, TopLevelError) {
device_signals::SignalCollectionError expected_error =
device_signals::SignalCollectionError::kConsentRequired;
device_signals::SignalsAggregationResponse expected_response;
expected_response.top_level_error = expected_error;
SetFakeResponse(expected_response);
auto error = api_test_utils::RunFunctionAndReturnError(
function_.get(), GetFakeUserContextJsonParams(), profile());
EXPECT_EQ(error, function_->GetError());
EXPECT_EQ(error, device_signals::ErrorToString(expected_error));
histogram_tester_.ExpectUniqueSample(
"Enterprise.DeviceSignals.Collection.Failure", signal_name(), 1);
histogram_tester_.ExpectUniqueSample(
"Enterprise.DeviceSignals.Collection.Failure.Hotfixes.TopLevelError",
expected_error,
1);
histogram_tester_.ExpectTotalCount(
"Enterprise.DeviceSignals.Collection.Failure.Hotfixes.Latency", 1);
histogram_tester_.ExpectTotalCount(
"Enterprise.DeviceSignals.Collection.Success", 0);
histogram_tester_.ExpectTotalCount(
"Enterprise.DeviceSignals.Collection.Success.Hotfixes.Latency", 0);
}
TEST_F(EnterpriseReportingPrivateGetHotfixesTest, CollectionError) {
device_signals::SignalCollectionError expected_error =
device_signals::SignalCollectionError::kMissingSystemService;
device_signals::HotfixSignalResponse hotfix_response;
hotfix_response.collection_error = expected_error;
device_signals::SignalsAggregationResponse expected_response;
expected_response.hotfix_signal_response = hotfix_response;
SetFakeResponse(expected_response);
auto error = api_test_utils::RunFunctionAndReturnError(
function_.get(), GetFakeUserContextJsonParams(), profile());
EXPECT_EQ(error, function_->GetError());
EXPECT_EQ(error, device_signals::ErrorToString(expected_error));
histogram_tester_.ExpectUniqueSample(
"Enterprise.DeviceSignals.Collection.Failure", signal_name(), 1);
histogram_tester_.ExpectUniqueSample(
"Enterprise.DeviceSignals.Collection.Failure.Hotfixes."
"CollectionLevelError",
expected_error,
1);
histogram_tester_.ExpectTotalCount(
"Enterprise.DeviceSignals.Collection.Failure.Hotfixes.Latency", 1);
histogram_tester_.ExpectTotalCount(
"Enterprise.DeviceSignals.Collection.Success", 0);
histogram_tester_.ExpectTotalCount(
"Enterprise.DeviceSignals.Collection.Success.Hotfixes.Latency", 0);
}
class EnterpriseReportingPrivateGetHotfixesInfoDisabledTest
: public EnterpriseReportingPrivateGetHotfixesTest {
protected:
void SetFeatureFlag() override {
scoped_features_.InitAndEnableFeatureWithParameters(
enterprise_signals::features::kNewEvSignalsEnabled,
{{"DisableHotfix", "true"}});
}
};
TEST_F(EnterpriseReportingPrivateGetHotfixesInfoDisabledTest,
FlagDisabled_Test) {
auto error = api_test_utils::RunFunctionAndReturnError(
function_.get(), GetFakeUserContextJsonParams(), profile());
EXPECT_EQ(error, function_->GetError());
EXPECT_EQ(error, device_signals::ErrorToString(
device_signals::SignalCollectionError::kUnsupported));
}
#endif
}