chromium/chrome/browser/ash/net/dns_over_https/templates_uri_resolver_impl_unittest.cc

// Copyright 2022 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/ash/net/dns_over_https/templates_uri_resolver_impl.h"

#include "ash/constants/ash_features.h"
#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/strings/stringprintf.h"
#include "base/test/repeating_test_future.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "base/test/test_future.h"
#include "base/values.h"
#include "chrome/browser/ash/policy/core/device_attributes_fake.h"
#include "chrome/browser/net/secure_dns_config.h"
#include "chrome/common/pref_names.h"
#include "chromeos/ash/components/dbus/shill/shill_property_changed_observer.h"
#include "chromeos/ash/components/install_attributes/stub_install_attributes.h"
#include "chromeos/ash/components/network/network_device_handler.h"
#include "chromeos/ash/components/network/network_handler.h"
#include "chromeos/ash/components/network/network_handler_test_helper.h"
#include "chromeos/ash/components/network/network_state.h"
#include "chromeos/ash/components/network/network_state_handler.h"
#include "chromeos/ash/components/network/network_ui_data.h"
#include "chromeos/ash/components/system/fake_statistics_provider.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/testing_pref_service.h"
#include "components/user_manager/fake_user_manager.h"
#include "components/user_manager/scoped_user_manager.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/cros_system_api/dbus/shill/dbus-constants.h"

namespace ash::dns_over_https {
namespace {

using ::testing::Contains;
using ::testing::ElementsAre;
using ::testing::Key;
using ::testing::UnorderedElementsAre;

constexpr const char kGoogleDns[] = "https://dns.google/dns-query{?dns}";
constexpr const char kTestSalt[] = "test-salt";

constexpr char kTemplateIdentifiers[] =
    "https://dns.google.alternativeuri/"
    "${USER_EMAIL}-${USER_EMAIL_DOMAIN}-${USER_EMAIL_NAME}-${DEVICE_"
    "DIRECTORY_"
    "ID}-${DEVICE_ASSET_ID}-${DEVICE_SERIAL_NUMBER}-${DEVICE_ANNOTATED_"
    "LOCATION}/"
    "dns-query{?dns}";
constexpr char kDisplayTemplateIdentifiers[] =
    "https://dns.google.alternativeuri/"
    "${[email protected]}-${testdomain.com}-${test-user}-${85729104-"
    "ef7a-5718d62e72ca}-${admin-provided-"
    "test-asset-ID}-${serial-number}-${admin-provided-test-location}/"
    "dns-query{?dns}";
constexpr char kDisplayTemplateIdentifiersUnaffiliated[] =
    "https://dns.google.alternativeuri/"
    "${[email protected]}-${testdomain.com}-${test-user}-${VALUE_NOT_"
    "AVAILABLE}-${VALUE_NOT_AVAILABLE}-${VALUE_NOT_AVAILABLE}-${VALUE_NOT_"
    "AVAILABLE}/dns-query{?dns}";

constexpr char kEffectiveTemplateIdentifiersUnaffiliated[] =
    "https://dns.google.alternativeuri/"
    "EAE2DCB2164EB64B695BC555C4EC45D01C8F0DF73CCD3321E45E5B49F22A22DF-"
    "0641BDB5149AF8B202F8EC96D8C256774CDFE9456CB12663DDF5897AFD91BC78-"
    "F3BA0BDE2D6E8DBE626D0B9ECF7862B18256C4D1807621F9F01AF06A3F603137-"
    "9AB270C9961EBBDF728F43396B0A25A1F198EA5F1F31719758C64E78839B928B-"
    "9AB270C9961EBBDF728F43396B0A25A1F198EA5F1F31719758C64E78839B928B-"
    "9AB270C9961EBBDF728F43396B0A25A1F198EA5F1F31719758C64E78839B928B-"
    "9AB270C9961EBBDF728F43396B0A25A1F198EA5F1F31719758C64E78839B928B/"
    "dns-query{?dns}";

constexpr char kEffectiveTemplateIdentifiers[] =
    "https://dns.google.alternativeuri/"
    "EAE2DCB2164EB64B695BC555C4EC45D01C8F0DF73CCD3321E45E5B49F22A22DF-"
    "0641BDB5149AF8B202F8EC96D8C256774CDFE9456CB12663DDF5897AFD91BC78-"
    "F3BA0BDE2D6E8DBE626D0B9ECF7862B18256C4D1807621F9F01AF06A3F603137-"
    "542BD404A979AB36D342019A18FFE0691B7763C1D145F2D7119FC1DCBBB7B248-"
    "2601D4E337D68B6EE97B338482E45F7D3670E78075490A7F9916321AF7B4539F-"
    "D60336AF57006D9FD327FD96F4B44F9067A09FB0A4DD83FB67EC0B2C472B9734-"
    "F7E37C960A2F15DD63CE0F694F29A3A76E4BE2700918E01FA22F0692098C6B28/"
    "dns-query{?dns}";

constexpr char kEffectiveTemplateIdentifiersNoSalt[] =
    "https://dns.google.alternativeuri/"
    "B07D2C5D119EB1881671C3B8D84CBE4FE3595C0C9ECBBF7670B18DDFDA072F66-"
    "E5E8A65918F11869E27483F8FB2014EF91D3E3C27DE3959FFFF365E59A8D3A4F-"
    "F85AC825D102B9F2D546AA1679EA991AE845994C1343730D564F3FCD0A2168C3-"
    "519F1980774A18DFCFC2003B4DC27E3497BF9B586E5901D7F2F6EDD1845613A9-"
    "505CBC62B85263246EE6FC89264D4039E5B55FD353885EC86C2DAF5CAA05399E-"
    "87278CD685B7191BB97AA713083522D99DBA30FD6F1DEC3C898E8745FB97E3E3-"
    "9CBE0CF3CA986C6BD8241B5A7030FBB807B7340AEFE0C53541B54545A888B551/"
    "dns-query{?dns}";

constexpr char kTestDeviceDirectoryId[] = "85729104-ef7a-5718d62e72ca";
constexpr char kTestDeviceAssetId[] = "admin-provided-test-asset-ID";
constexpr char kTestDeviceAnnotatedLocation[] = "admin-provided-test-location";
constexpr char kTestSerialNumber[] = "serial-number";

class DevicePropertyObserver : public ash::ShillPropertyChangedObserver {
 public:
  explicit DevicePropertyObserver(const std::string& path) : path_(path) {
    ash::ShillDeviceClient::Get()->AddPropertyChangedObserver(
        dbus::ObjectPath(path_), this);
  }
  ~DevicePropertyObserver() override {
    ash::ShillDeviceClient::Get()->RemovePropertyChangedObserver(
        dbus::ObjectPath(path_), this);
  }
  void Wait() { return future_.Take(); }

 private:
  const std::string path_;
  void OnPropertyChanged(const std::string& name,
                         const base::Value& value) override {
    future_.AddValue();
  }
  base::test::RepeatingTestFuture<void> future_;
};

// Sets an IP address for the device identified by `device_path` and waits for
// the observers to be notified by the change.
bool SetIpAddress(const std::string& device_path,
                  const std::string& ipconfig_path,
                  const std::string& ip_address) {
  DevicePropertyObserver property_observer(device_path);
  base::Value::List ip_configs;
  ip_configs.Append(ipconfig_path);
  ShillDeviceClient::Get()->GetTestInterface()->SetDeviceProperty(
      device_path, shill::kIPConfigsProperty,
      base::Value(std::move(ip_configs)),
      /*notify_changed=*/true);
  property_observer.Wait();

  base::test::TestFuture<bool> wait_for_ip_change;
  ShillIPConfigClient::Get()->SetProperty(
      dbus::ObjectPath(ipconfig_path), shill::kAddressProperty,
      base::Value(ip_address), wait_for_ip_change.GetRepeatingCallback());

  return wait_for_ip_change.Wait();
}

}  // namespace

class TemplatesUriResolverImplTest : public testing::Test {
 public:
  TemplatesUriResolverImplTest() = default;

  TemplatesUriResolverImplTest(const TemplatesUriResolverImplTest&) = delete;
  TemplatesUriResolverImplTest& operator=(const TemplatesUriResolverImplTest&) =
      delete;

  void SetUp() override {
    pref_service_.registry()->RegisterStringPref(prefs::kDnsOverHttpsMode,
                                                 SecureDnsConfig::kModeOff);
    pref_service_.registry()->RegisterStringPref(prefs::kDnsOverHttpsTemplates,
                                                 "");
    pref_service_.registry()->RegisterStringPref(
        prefs::kDnsOverHttpsTemplatesWithIdentifiers, "");
    pref_service_.registry()->RegisterStringPref(prefs::kDnsOverHttpsSalt, "");

    fake_user_manager_ = new user_manager::FakeUserManager(&pref_service_);
    scoped_user_manager_ = std::make_unique<user_manager::ScopedUserManager>(
        base::WrapUnique(fake_user_manager_.get()));

    doh_template_uri_resolver_ = std::make_unique<TemplatesUriResolverImpl>();

    // Set up fake device attributes.
    std::unique_ptr<policy::FakeDeviceAttributes> device_attributes =
        std::make_unique<policy::FakeDeviceAttributes>();
    device_attributes->SetFakeDirectoryApiId(kTestDeviceDirectoryId);
    device_attributes->SetFakeDeviceAssetId(kTestDeviceAssetId);
    device_attributes->SetFakeDeviceAnnotatedLocation(
        kTestDeviceAnnotatedLocation);
    device_attributes->SetFakeDeviceSerialNumber(kTestSerialNumber);

    network_handler_test_helper_ =
        std::make_unique<ash::NetworkHandlerTestHelper>();
    network_handler_test_helper_->AddDefaultProfiles();

    doh_template_uri_resolver_->SetDeviceAttributesForTesting(
        std::move(device_attributes));
  }

  void TearDown() override { scoped_user_manager_.reset(); }

  void SetUpAffiliatedUser() {
    const AccountId account_id(AccountId::FromUserEmailGaiaId(
        "[email protected]", "1234567890"));
    fake_user_manager_->AddUserWithAffiliation(account_id, true);
  }

  void SetUpUnaffiliatedUser() {
    const AccountId account_id(AccountId::FromUserEmailGaiaId(
        "[email protected]", "1234567890"));
    fake_user_manager_->AddUser(account_id);
  }

  void ChangeNetworkOncSource(const std::string& path,
                              ::onc::ONCSource onc_source) {
    std::unique_ptr<ash::NetworkUIData> ui_data =
        ash::NetworkUIData::CreateFromONC(onc_source);
    network_handler_test_helper_->SetServiceProperty(
        path, shill::kUIDataProperty, base::Value(ui_data->GetAsJson()));
  }

  void SetUpDOHSecureModeWithSalt(std::string salt) {
    pref_service()->Set(prefs::kDnsOverHttpsMode,
                        base::Value(SecureDnsConfig::kModeSecure));
    pref_service()->Set(prefs::kDnsOverHttpsSalt, base::Value(salt));
  }

  void SetUpDOHTemplatesWithIdentifiers(std::string_view identifier) {
    pref_service()->Set(prefs::kDnsOverHttpsTemplatesWithIdentifiers,
                        base::Value(identifier));
  }

  void SetUpDOHGoogleDnsTemplate() {
    pref_service()->Set(prefs::kDnsOverHttpsTemplates, base::Value(kGoogleDns));
  }

  std::string GetDisplayTemplates() {
    return doh_template_uri_resolver_->GetDisplayTemplates();
  }

  std::string GetEffectiveTemplates() {
    return doh_template_uri_resolver_->GetEffectiveTemplates();
  }

  PrefService* pref_service() { return &pref_service_; }
  user_manager::FakeUserManager* user_manager() { return fake_user_manager_; }

 protected:
  base::test::TaskEnvironment task_environment_;
  std::unique_ptr<TemplatesUriResolverImpl> doh_template_uri_resolver_;
  std::unique_ptr<ash::NetworkHandlerTestHelper> network_handler_test_helper_;

 private:
  TestingPrefServiceSimple pref_service_;
  raw_ptr<user_manager::FakeUserManager, DanglingUntriaged> fake_user_manager_;
  std::unique_ptr<user_manager::ScopedUserManager> scoped_user_manager_;
  ScopedStubInstallAttributes test_install_attributes_{
      StubInstallAttributes::CreateCloudManaged("fake-domain", "fake-id")};
};

// Test that verifies the correct substitution of placeholders in the template
// uri.
TEST_F(TemplatesUriResolverImplTest, TemplatesWithIdentifiers) {
  SetUpAffiliatedUser();
  SetUpDOHSecureModeWithSalt(kTestSalt);
  SetUpDOHTemplatesWithIdentifiers(kTemplateIdentifiers);
  SetUpDOHGoogleDnsTemplate();

  doh_template_uri_resolver_->Update(pref_service());

  EXPECT_EQ(GetDisplayTemplates(), kDisplayTemplateIdentifiers);
  EXPECT_EQ(GetEffectiveTemplates(), kEffectiveTemplateIdentifiers);
  EXPECT_TRUE(doh_template_uri_resolver_->GetDohWithIdentifiersActive());

  // `prefs::kDnsOverHttpsTemplates` should apply when
  // `prefs::kDnsOverHttpsTemplatesWithIdentifiers` is cleared.
  pref_service()->ClearPref(prefs::kDnsOverHttpsTemplatesWithIdentifiers);
  doh_template_uri_resolver_->Update(pref_service());
  EXPECT_EQ(GetEffectiveTemplates(), kGoogleDns);
  EXPECT_FALSE(doh_template_uri_resolver_->GetDohWithIdentifiersActive());
}

// Tests that only user indentifiers are replaced in
// `prefs::kDnsOverHttpsTemplatesWithIdentifiers` if the user is not affiliated.
TEST_F(TemplatesUriResolverImplTest, TemplatesWithIdentifiersUnaffiliated) {
  SetUpUnaffiliatedUser();
  SetUpDOHSecureModeWithSalt(kTestSalt);
  SetUpDOHTemplatesWithIdentifiers(kTemplateIdentifiers);
  SetUpDOHGoogleDnsTemplate();

  doh_template_uri_resolver_->Update(pref_service());

  EXPECT_EQ(GetDisplayTemplates(), kDisplayTemplateIdentifiersUnaffiliated);
  EXPECT_EQ(GetEffectiveTemplates(), kEffectiveTemplateIdentifiersUnaffiliated);
  EXPECT_TRUE(doh_template_uri_resolver_->GetDohWithIdentifiersActive());
}

// Verifies that, when the pref sets a list of template URI separated by space,
// all template URIs are being resolved.
TEST_F(TemplatesUriResolverImplTest, MultipleTemplatesWithIdentifiers) {
  SetUpAffiliatedUser();
  SetUpDOHSecureModeWithSalt(kTestSalt);
  SetUpDOHGoogleDnsTemplate();
  std::string multiple_templates = base::StringPrintf(
      "%s %s %s", kTemplateIdentifiers, kGoogleDns, kTemplateIdentifiers);
  SetUpDOHTemplatesWithIdentifiers(multiple_templates);
  doh_template_uri_resolver_->Update(pref_service());

  std::string expected_multiple_templates =
      base::StringPrintf("%s %s %s", kEffectiveTemplateIdentifiers, kGoogleDns,
                         kEffectiveTemplateIdentifiers);
  EXPECT_EQ(GetEffectiveTemplates(), expected_multiple_templates);
  EXPECT_TRUE(doh_template_uri_resolver_->GetDohWithIdentifiersActive());
}

TEST_F(TemplatesUriResolverImplTest, TemplatesWithIdentifiersNoSalt) {
  SetUpAffiliatedUser();
  SetUpDOHSecureModeWithSalt("");
  SetUpDOHTemplatesWithIdentifiers(kTemplateIdentifiers);
  SetUpDOHGoogleDnsTemplate();

  doh_template_uri_resolver_->Update(pref_service());

  EXPECT_EQ(GetDisplayTemplates(), kDisplayTemplateIdentifiers);
  EXPECT_EQ(GetEffectiveTemplates(), kEffectiveTemplateIdentifiersNoSalt);
  EXPECT_TRUE(doh_template_uri_resolver_->GetDohWithIdentifiersActive());

  // `prefs::kDnsOverHttpsTemplates` should apply when
  // `prefs::kDnsOverHttpsTemplatesWithIdentifiers` is cleared.
  pref_service()->ClearPref(prefs::kDnsOverHttpsTemplatesWithIdentifiers);
  doh_template_uri_resolver_->Update(pref_service());
  EXPECT_EQ(GetEffectiveTemplates(), kGoogleDns);
}

constexpr char kTemplateIdentifiersWithIp[] =
    "https://dns.google.alternativeuri/${DEVICE_IP_ADDRESSES}";

constexpr char kEffectiveTemplateIdentifiersWithIp[] =
    "https://dns.google.alternativeuri/"
    "001064000001002000000000000000000100000000000001";
constexpr char kDisplayTemplateIdentifiersWithIp[] =
    "https://dns.google.alternativeuri/${100.0.0.1}${::100:0:0:1}";

constexpr char kNoReplacementEffectiveTemplateIdentifiersWithIp[] =
    "https://dns.google.alternativeuri/";
constexpr char kNoReplacementDisplayTemplateIdentifiersWithIp[] =
    "https://dns.google.alternativeuri/";

// Verifies IP addresses placeholder replacement for the
// DnsOverHttpsTemplatesWithIdentifiers policy when the user is not affiliated.
// More specifically, it tests that IP addresses are only included if the
// default network is managed by user policy.
TEST_F(TemplatesUriResolverImplTest,
       TemplatesWithIdentifiersIpAddressUnaffiliatedUser) {
  SetUpUnaffiliatedUser();
  SetUpDOHSecureModeWithSalt("");
  SetUpDOHTemplatesWithIdentifiers(kTemplateIdentifiersWithIp);
  const ash::NetworkStateHandler* network_state_handler =
      ash::NetworkHandler::Get()->network_state_handler();

  const ash::NetworkState* network = network_state_handler->DefaultNetwork();

  // Verify that the IP addresses are not replaced for unmanaged networks.
  doh_template_uri_resolver_->Update(pref_service());
  EXPECT_EQ(network->onc_source(), ::onc::ONCSource::ONC_SOURCE_UNKNOWN);
  EXPECT_EQ(GetDisplayTemplates(),
            kNoReplacementDisplayTemplateIdentifiersWithIp);
  EXPECT_EQ(GetEffectiveTemplates(),
            kNoReplacementEffectiveTemplateIdentifiersWithIp);

  // Verify that the IP addresses are replaced for networks managed by user
  // policy.
  ChangeNetworkOncSource(network->path(),
                         ::onc::ONCSource::ONC_SOURCE_USER_POLICY);
  doh_template_uri_resolver_->Update(pref_service());
  EXPECT_EQ(GetDisplayTemplates(), kDisplayTemplateIdentifiersWithIp);
  EXPECT_EQ(GetEffectiveTemplates(), kEffectiveTemplateIdentifiersWithIp);

  // Verify that the IP addresses are not replaced for networks managed by
  // device policy.
  ChangeNetworkOncSource(network->path(),
                         ::onc::ONCSource::ONC_SOURCE_DEVICE_POLICY);
  doh_template_uri_resolver_->Update(pref_service());
  EXPECT_EQ(GetDisplayTemplates(),
            kNoReplacementDisplayTemplateIdentifiersWithIp);
  EXPECT_EQ(GetEffectiveTemplates(),
            kNoReplacementEffectiveTemplateIdentifiersWithIp);
}

// Verifies IP addresses placeholder replacement for the
// DnsOverHttpsTemplatesWithIdentifiers policy when the user is affiliated.
// More specifically, it tests that IP addresses are included if the
// default network is managed by user policy or device policy.
TEST_F(TemplatesUriResolverImplTest,
       TemplatesWithIdentifiersIpAddressAffiliatedUser) {
  SetUpAffiliatedUser();
  SetUpDOHSecureModeWithSalt("");
  SetUpDOHTemplatesWithIdentifiers(kTemplateIdentifiersWithIp);
  const ash::NetworkStateHandler* network_state_handler =
      ash::NetworkHandler::Get()->network_state_handler();

  const ash::NetworkState* network = network_state_handler->DefaultNetwork();

  // Verify that the IP is not replaced for unmanaged networks.
  doh_template_uri_resolver_->Update(pref_service());
  EXPECT_EQ(network->onc_source(), ::onc::ONCSource::ONC_SOURCE_UNKNOWN);
  EXPECT_EQ(GetDisplayTemplates(),
            kNoReplacementDisplayTemplateIdentifiersWithIp);
  EXPECT_EQ(GetEffectiveTemplates(),
            kNoReplacementEffectiveTemplateIdentifiersWithIp);

  ChangeNetworkOncSource(network->path(),
                         ::onc::ONCSource::ONC_SOURCE_USER_POLICY);
  doh_template_uri_resolver_->Update(pref_service());
  EXPECT_EQ(GetDisplayTemplates(), kDisplayTemplateIdentifiersWithIp);
  EXPECT_EQ(GetEffectiveTemplates(), kEffectiveTemplateIdentifiersWithIp);

  ChangeNetworkOncSource(network->path(),
                         ::onc::ONCSource::ONC_SOURCE_DEVICE_POLICY);
  doh_template_uri_resolver_->Update(pref_service());
  EXPECT_EQ(GetDisplayTemplates(), kDisplayTemplateIdentifiersWithIp);
  EXPECT_EQ(GetEffectiveTemplates(), kEffectiveTemplateIdentifiersWithIp);
}

TEST_F(TemplatesUriResolverImplTest,
       TemplatesWithIdentifiersIpProtocolUpdates) {
  SetUpAffiliatedUser();
  SetUpDOHSecureModeWithSalt("");
  SetUpDOHTemplatesWithIdentifiers(kTemplateIdentifiersWithIp);

  const ash::NetworkStateHandler* network_state_handler =
      ash::NetworkHandler::Get()->network_state_handler();
  const ash::NetworkState* network = network_state_handler->DefaultNetwork();
  ChangeNetworkOncSource(network->path(),
                         ::onc::ONCSource::ONC_SOURCE_USER_POLICY);

  SetIpAddress(network->device_path(), /*ipconfig_path=*/"",
               /*ipconfig_path=*/"");
  doh_template_uri_resolver_->Update(pref_service());
  EXPECT_EQ(GetDisplayTemplates(),
            kNoReplacementDisplayTemplateIdentifiersWithIp);
  EXPECT_EQ(GetEffectiveTemplates(),
            kNoReplacementEffectiveTemplateIdentifiersWithIp);

  SetIpAddress(network->device_path(), "ipconfig_v4_path", "100.0.0.1");
  doh_template_uri_resolver_->Update(pref_service());
  EXPECT_EQ(GetDisplayTemplates(),
            "https://dns.google.alternativeuri/${100.0.0.1}");
  EXPECT_EQ(GetEffectiveTemplates(),
            "https://dns.google.alternativeuri/001064000001");

  SetIpAddress(network->device_path(), "ipconfig_v6_path", "0:0:0:0:100:0:0:1");
  doh_template_uri_resolver_->Update(pref_service());
  EXPECT_EQ(GetDisplayTemplates(),
            "https://dns.google.alternativeuri/${::100:0:0:1}");
  EXPECT_EQ(
      GetEffectiveTemplates(),
      "https://dns.google.alternativeuri/002000000000000000000100000000000001");
}

// Verify that IP replacement is not happening when a VPN is connected.
TEST_F(TemplatesUriResolverImplTest, TemplatesWithIdentifiersIpWithVpn) {
  SetUpAffiliatedUser();
  SetUpDOHSecureModeWithSalt("");
  SetUpDOHTemplatesWithIdentifiers(kTemplateIdentifiersWithIp);

  const ash::NetworkState* network =
      ash::NetworkHandler::Get()->network_state_handler()->DefaultNetwork();
  ChangeNetworkOncSource(network->path(),
                         ::onc::ONCSource::ONC_SOURCE_USER_POLICY);

  network_handler_test_helper_->SetServiceProperty(
      "/service/eth1", shill::kStateProperty, base::Value(shill::kStateIdle));
  network_handler_test_helper_->SetServiceProperty(
      "/service/wifi1", shill::kStateProperty, base::Value(shill::kStateIdle));
  network_handler_test_helper_->SetServiceProperty(
      "/service/vpn1", shill::kStateProperty, base::Value(shill::kStateOnline));

  doh_template_uri_resolver_->Update(pref_service());
  EXPECT_EQ(GetDisplayTemplates(),
            kNoReplacementDisplayTemplateIdentifiersWithIp);
  EXPECT_EQ(GetEffectiveTemplates(),
            kNoReplacementEffectiveTemplateIdentifiersWithIp);
}

}  // namespace ash::dns_over_https