chromium/chrome/browser/enterprise/connectors/device_trust/signals/ash/ash_signals_filterer_unittest.cc

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/enterprise/connectors/device_trust/signals/ash/ash_signals_filterer.h"

#include "chromeos/ash/components/install_attributes/stub_install_attributes.h"
#include "components/device_signals/core/common/signals_constants.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace enterprise_connectors {

namespace {
constexpr int kFakeSafeBrowsingProtectionLevel = 1;
constexpr char kFakeDeviceHostName[] = "fake_device_host_name";
constexpr char kFakeDeviceModel[] = "fake_device_model";
constexpr char kFakeDisplayName[] = "fake_display_name";
constexpr char kFakeImei[] = "fake_imei";
constexpr char kFakeMacAddress[] = "fake_mac_address";
constexpr char kFakeMeid[] = "fake_meid";
constexpr char kFakeSerialNumber[] = "fake_serial_number";
constexpr char kFakeSystemDnsServer[] = "fake_system_dns_server";
}  // namespace

// Creates a signal payload which contains all device identifying signals and
// some non device identifying signals.
base::Value::Dict CreateDeviceSignals() {
  base::Value::Dict signals;
  signals.Set(device_signals::names::kSafeBrowsingProtectionLevel,
              kFakeSafeBrowsingProtectionLevel);
  signals.Set(device_signals::names::kDeviceHostName, kFakeDeviceHostName);
  signals.Set(device_signals::names::kDeviceModel, kFakeDeviceModel);
  signals.Set(device_signals::names::kDisplayName, kFakeDisplayName);
  signals.Set(device_signals::names::kSerialNumber, kFakeSerialNumber);

  base::Value::List imei_list;
  imei_list.Append(kFakeImei);
  signals.Set(device_signals::names::kImei, std::move(imei_list));

  base::Value::List mac_addresses_list;
  mac_addresses_list.Append(kFakeMacAddress);
  signals.Set(device_signals::names::kMacAddresses,
              std::move(mac_addresses_list));

  base::Value::List meid_list;
  meid_list.Append(kFakeMeid);
  signals.Set(device_signals::names::kMeid, std::move(meid_list));

  base::Value::List system_dns_list;
  system_dns_list.Append(kFakeSystemDnsServer);
  signals.Set(device_signals::names::kSystemDnsServers,
              std::move(system_dns_list));

  return signals;
}

// Creates a small signal payload which does not contain all device identifying
// signals.
base::Value::Dict CreateIncompleteDeviceSignals() {
  base::Value::Dict signals;

  signals.Set(device_signals::names::kSerialNumber, kFakeSerialNumber);
  signals.Set(device_signals::names::kDeviceModel, kFakeDeviceModel);

  return signals;
}

void ValidateNonDeviceIdentifyingSignals(base::Value::Dict& signals) {
  EXPECT_EQ(
      *signals.FindInt(device_signals::names::kSafeBrowsingProtectionLevel),
      kFakeSafeBrowsingProtectionLevel);
  EXPECT_EQ(*signals.FindString(device_signals::names::kDeviceModel),
            kFakeDeviceModel);
}

void ValidateDeviceIdentifyingSignalsExist(base::Value::Dict& signals) {
  EXPECT_EQ(*signals.FindString(device_signals::names::kDeviceHostName),
            kFakeDeviceHostName);
  EXPECT_EQ(*signals.FindString(device_signals::names::kDisplayName),
            kFakeDisplayName);
  EXPECT_EQ(*signals.FindString(device_signals::names::kSerialNumber),
            kFakeSerialNumber);

  base::Value::List* imei_list = signals.FindList(device_signals::names::kImei);
  EXPECT_EQ(imei_list->size(), 1u);
  EXPECT_EQ(imei_list->front(), kFakeImei);

  base::Value::List* mac_addresses_list =
      signals.FindList(device_signals::names::kMacAddresses);
  EXPECT_EQ(mac_addresses_list->size(), 1u);
  EXPECT_EQ(mac_addresses_list->front(), kFakeMacAddress);

  base::Value::List* meid_list = signals.FindList(device_signals::names::kMeid);
  EXPECT_EQ(meid_list->size(), 1u);
  EXPECT_EQ(meid_list->front(), kFakeMeid);

  base::Value::List* system_dns_servers_list =
      signals.FindList(device_signals::names::kSystemDnsServers);
  EXPECT_EQ(system_dns_servers_list->size(), 1u);
  EXPECT_EQ(system_dns_servers_list->front(), kFakeSystemDnsServer);
}

void ValidateDeviceIdentifyingSignalsRemoved(base::Value::Dict& signals) {
  EXPECT_EQ(signals.Find(device_signals::names::kDeviceHostName), nullptr);
  EXPECT_EQ(signals.Find(device_signals::names::kDisplayName), nullptr);
  EXPECT_EQ(signals.Find(device_signals::names::kImei), nullptr);
  EXPECT_EQ(signals.Find(device_signals::names::kMacAddresses), nullptr);
  EXPECT_EQ(signals.Find(device_signals::names::kMeid), nullptr);
  EXPECT_EQ(signals.Find(device_signals::names::kSerialNumber), nullptr);
  EXPECT_EQ(signals.Find(device_signals::names::kSystemDnsServers), nullptr);
}

class AshSignalsFiltererTest : public testing::Test {
 public:
  void SetDeviceManagement(bool is_managed) {
    if (is_managed) {
      StubInstallAttributes()->SetCloudManaged("test_domain", "test_device_id");
    } else {
      StubInstallAttributes()->SetConsumerOwned();
    }
  }

  ash::StubInstallAttributes* StubInstallAttributes() {
    return stub_install_attributes_.Get();
  }

  ash::ScopedStubInstallAttributes stub_install_attributes_;
};

// Test that nothing is filtered if the device is managed
TEST_F(AshSignalsFiltererTest, Filter_DeviceManaged) {
  SetDeviceManagement(true);
  base::Value::Dict signals = CreateDeviceSignals();

  AshSignalsFilterer filterer;
  filterer.Filter(signals);

  ValidateNonDeviceIdentifyingSignals(signals);
  ValidateDeviceIdentifyingSignalsExist(signals);
}

// Test that all device identifying signals are filtered if the device is
// unmanaged.
TEST_F(AshSignalsFiltererTest, Filter_DeviceUnmanaged) {
  SetDeviceManagement(false);
  base::Value::Dict signals = CreateDeviceSignals();

  AshSignalsFilterer filterer;
  filterer.Filter(signals);

  ValidateNonDeviceIdentifyingSignals(signals);
  ValidateDeviceIdentifyingSignalsRemoved(signals);
}

// Test that all device identifying signals are filtered if the device is
// unmanaged even if it does not contain all device identifying signals.
TEST_F(AshSignalsFiltererTest, Filter_DeviceUnmanaged_IncompleteSignals) {
  SetDeviceManagement(false);
  base::Value::Dict signals = CreateIncompleteDeviceSignals();

  AshSignalsFilterer filterer;
  filterer.Filter(signals);

  ValidateDeviceIdentifyingSignalsRemoved(signals);
}

}  // namespace enterprise_connectors