| // 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/ui/webui/settings/settings_secure_dns_handler.h" |
| |
| #include "base/test/metrics/histogram_tester.h" |
| #include "build/build_config.h" |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/net/dns_probe_test_util.h" |
| #include "chrome/browser/net/dns_util.h" |
| #include "chrome/common/chrome_features.h" |
| #include "chrome/common/pref_names.h" |
| #include "chrome/test/base/in_process_browser_test.h" |
| #include "components/country_codes/country_codes.h" |
| #include "components/policy/core/browser/browser_policy_connector.h" |
| #include "components/policy/core/common/mock_configuration_policy_provider.h" |
| #include "components/policy/policy_constants.h" |
| #include "components/prefs/pref_service.h" |
| #include "content/public/test/test_web_ui.h" |
| #include "net/dns/public/resolve_error_info.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| #if defined(OS_WIN) |
| #include "base/win/win_util.h" |
| #endif |
| |
| using net::DohProviderEntry; |
| using testing::_; |
| using testing::Return; |
| |
| namespace settings { |
| |
| namespace { |
| |
| constexpr char kGetSecureDnsResolverList[] = "getSecureDnsResolverList"; |
| constexpr char kValidateCustomDnsEntry[] = "validateCustomDnsEntry"; |
| constexpr char kProbeCustomDnsTemplate[] = "probeCustomDnsTemplate"; |
| constexpr char kRecordUserDropdownInteraction[] = |
| "recordUserDropdownInteraction"; |
| constexpr char kWebUiFunctionName[] = "webUiCallbackName"; |
| |
| const std::vector<DohProviderEntry>& GetDohProviderListForTesting() { |
| static const base::NoDestructor<std::vector<DohProviderEntry>> test_providers{ |
| { |
| DohProviderEntry( |
| "Provider_Global1", net::DohProviderIdForHistogram(-1), |
| {} /*ip_strs */, {} /* dot_hostnames */, |
| "https://global1.provider/dns-query{?dns}", |
| "Global Provider 1" /* ui_name */, |
| "https://global1.provider/privacy_policy/" /* privacy_policy */, |
| true /* display_globally */, {} /* display_countries */), |
| DohProviderEntry( |
| "Provider_NoDisplay", net::DohProviderIdForHistogram(-2), |
| {} /*ip_strs */, {} /* dot_hostnames */, |
| "https://nodisplay.provider/dns-query{?dns}", |
| "No Display Provider" /* ui_name */, |
| "https://nodisplay.provider/privacy_policy/" /* privacy_policy */, |
| false /* display_globally */, {} /* display_countries */), |
| DohProviderEntry( |
| "Provider_EE_FR", net::DohProviderIdForHistogram(-3), |
| {} /*ip_strs */, {} /* dot_hostnames */, |
| "https://ee.fr.provider/dns-query{?dns}", |
| "EE/FR Provider" /* ui_name */, |
| "https://ee.fr.provider/privacy_policy/" /* privacy_policy */, |
| false /* display_globally */, |
| {"EE", "FR"} /* display_countries */), |
| DohProviderEntry( |
| "Provider_FR", net::DohProviderIdForHistogram(-4), |
| {} /*ip_strs */, {} /* dot_hostnames */, |
| "https://fr.provider/dns-query{?dns}", |
| "FR Provider" /* ui_name */, |
| "https://fr.provider/privacy_policy/" /* privacy_policy */, |
| false /* display_globally */, {"FR"} /* display_countries */), |
| DohProviderEntry( |
| "Provider_Global2", net::DohProviderIdForHistogram(-5), |
| {} /*ip_strs */, {} /* dot_hostnames */, |
| "https://global2.provider/dns-query{?dns}", |
| "Global Provider 2" /* ui_name */, |
| "https://global2.provider/privacy_policy/" /* privacy_policy */, |
| true /* display_globally */, {} /* display_countries */), |
| }}; |
| return *test_providers; |
| } |
| |
| bool FindDropdownItem(const base::Value& resolvers, |
| const std::string& name, |
| const std::string& value, |
| const std::string& policy) { |
| base::Value dict(base::Value::Type::DICTIONARY); |
| dict.SetKey("name", base::Value(name)); |
| dict.SetKey("value", base::Value(value)); |
| dict.SetKey("policy", base::Value(policy)); |
| |
| return std::find(resolvers.GetList().begin(), resolvers.GetList().end(), |
| dict) != resolvers.GetList().end(); |
| } |
| |
| } // namespace |
| |
| class TestSecureDnsHandler : public SecureDnsHandler { |
| public: |
| // Pull WebUIMessageHandler::set_web_ui() into public so tests can call it. |
| using SecureDnsHandler::set_web_ui; |
| }; |
| |
| class SecureDnsHandlerTest : public InProcessBrowserTest { |
| protected: |
| #if defined(OS_WIN) |
| SecureDnsHandlerTest() |
| // Mark as not enterprise managed to prevent the secure DNS mode from |
| // being downgraded to off. |
| : scoped_domain_(false) {} |
| #else |
| SecureDnsHandlerTest() = default; |
| #endif |
| ~SecureDnsHandlerTest() override = default; |
| |
| // InProcessBrowserTest: |
| void SetUpInProcessBrowserTestFixture() override { |
| // Initialize user policy. |
| ON_CALL(provider_, IsInitializationComplete(_)).WillByDefault(Return(true)); |
| policy::BrowserPolicyConnector::SetPolicyProviderForTesting(&provider_); |
| } |
| |
| void SetUpOnMainThread() override { |
| handler_ = std::make_unique<TestSecureDnsHandler>(); |
| handler_->set_web_ui(&web_ui_); |
| handler_->RegisterMessages(); |
| handler_->AllowJavascriptForTesting(); |
| base::RunLoop().RunUntilIdle(); |
| } |
| |
| void TearDownOnMainThread() override { handler_.reset(); } |
| |
| // Updates out-params from the last message sent to WebUI about a secure DNS |
| // change. Returns false if the message was invalid or not found. |
| bool GetLastSettingsChangedMessage( |
| std::string* secure_dns_mode, |
| std::vector<std::string>* secure_dns_templates, |
| int* management_mode) { |
| for (auto it = web_ui_.call_data().rbegin(); |
| it != web_ui_.call_data().rend(); ++it) { |
| const content::TestWebUI::CallData* data = it->get(); |
| if (data->function_name() != "cr.webUIListenerCallback" || |
| !data->arg1()->is_string() || |
| data->arg1()->GetString() != "secure-dns-setting-changed") { |
| continue; |
| } |
| |
| const base::DictionaryValue* dict = nullptr; |
| if (!data->arg2()->GetAsDictionary(&dict)) |
| return false; |
| |
| // Get the secure DNS mode. |
| if (!dict->FindStringPath("mode")) |
| return false; |
| *secure_dns_mode = *dict->FindStringPath("mode"); |
| |
| // Get the secure DNS templates. |
| if (!dict->FindListPath("templates")) |
| return false; |
| secure_dns_templates->clear(); |
| for (const auto& template_str : |
| dict->FindListPath("templates")->GetList()) { |
| if (!template_str.is_string()) |
| return false; |
| secure_dns_templates->push_back(template_str.GetString()); |
| } |
| |
| // Get the forced management description. |
| if (!dict->FindIntPath("managementMode")) |
| return false; |
| *management_mode = *dict->FindIntPath("managementMode"); |
| |
| return true; |
| } |
| return false; |
| } |
| |
| // Sets a policy update which will cause power pref managed change. |
| void SetPolicyForPolicyKey(policy::PolicyMap* policy_map, |
| const std::string& policy_key, |
| std::unique_ptr<base::Value> value) { |
| policy_map->Set(policy_key, policy::POLICY_LEVEL_MANDATORY, |
| policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD, |
| std::move(value), nullptr); |
| provider_.UpdateChromePolicy(*policy_map); |
| base::RunLoop().RunUntilIdle(); |
| } |
| |
| std::unique_ptr<TestSecureDnsHandler> handler_; |
| content::TestWebUI web_ui_; |
| policy::MockConfigurationPolicyProvider provider_; |
| |
| private: |
| #if defined(OS_WIN) |
| base::win::ScopedDomainStateForTesting scoped_domain_; |
| #endif |
| |
| DISALLOW_COPY_AND_ASSIGN(SecureDnsHandlerTest); |
| }; |
| |
| IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, SecureDnsModes) { |
| PrefService* local_state = g_browser_process->local_state(); |
| std::string secure_dns_mode; |
| std::vector<std::string> secure_dns_templates; |
| int management_mode; |
| |
| local_state->SetString(prefs::kDnsOverHttpsMode, |
| chrome_browser_net::kDnsOverHttpsModeOff); |
| EXPECT_TRUE(GetLastSettingsChangedMessage( |
| &secure_dns_mode, &secure_dns_templates, &management_mode)); |
| EXPECT_EQ(chrome_browser_net::kDnsOverHttpsModeOff, secure_dns_mode); |
| |
| local_state->SetString(prefs::kDnsOverHttpsMode, |
| chrome_browser_net::kDnsOverHttpsModeAutomatic); |
| EXPECT_TRUE(GetLastSettingsChangedMessage( |
| &secure_dns_mode, &secure_dns_templates, &management_mode)); |
| EXPECT_EQ(chrome_browser_net::kDnsOverHttpsModeAutomatic, secure_dns_mode); |
| |
| local_state->SetString(prefs::kDnsOverHttpsMode, |
| chrome_browser_net::kDnsOverHttpsModeSecure); |
| EXPECT_TRUE(GetLastSettingsChangedMessage( |
| &secure_dns_mode, &secure_dns_templates, &management_mode)); |
| EXPECT_EQ(chrome_browser_net::kDnsOverHttpsModeSecure, secure_dns_mode); |
| |
| local_state->SetString(prefs::kDnsOverHttpsMode, "unknown"); |
| EXPECT_TRUE(GetLastSettingsChangedMessage( |
| &secure_dns_mode, &secure_dns_templates, &management_mode)); |
| EXPECT_EQ(chrome_browser_net::kDnsOverHttpsModeOff, secure_dns_mode); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, SecureDnsPolicy) { |
| policy::PolicyMap policy_map; |
| SetPolicyForPolicyKey(&policy_map, policy::key::kDnsOverHttpsMode, |
| std::make_unique<base::Value>( |
| chrome_browser_net::kDnsOverHttpsModeAutomatic)); |
| |
| PrefService* local_state = g_browser_process->local_state(); |
| local_state->SetString(prefs::kDnsOverHttpsMode, |
| chrome_browser_net::kDnsOverHttpsModeSecure); |
| |
| std::string secure_dns_mode; |
| std::vector<std::string> secure_dns_templates; |
| int management_mode; |
| EXPECT_TRUE(GetLastSettingsChangedMessage( |
| &secure_dns_mode, &secure_dns_templates, &management_mode)); |
| EXPECT_EQ(chrome_browser_net::kDnsOverHttpsModeAutomatic, secure_dns_mode); |
| EXPECT_EQ(static_cast<int>( |
| chrome_browser_net::SecureDnsUiManagementMode::kNoOverride), |
| management_mode); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, SecureDnsPolicyChange) { |
| policy::PolicyMap policy_map; |
| SetPolicyForPolicyKey(&policy_map, policy::key::kDnsOverHttpsMode, |
| std::make_unique<base::Value>( |
| chrome_browser_net::kDnsOverHttpsModeAutomatic)); |
| |
| std::string secure_dns_mode; |
| std::vector<std::string> secure_dns_templates; |
| int management_mode; |
| EXPECT_TRUE(GetLastSettingsChangedMessage( |
| &secure_dns_mode, &secure_dns_templates, &management_mode)); |
| EXPECT_EQ(chrome_browser_net::kDnsOverHttpsModeAutomatic, secure_dns_mode); |
| EXPECT_EQ(static_cast<int>( |
| chrome_browser_net::SecureDnsUiManagementMode::kNoOverride), |
| management_mode); |
| |
| SetPolicyForPolicyKey( |
| &policy_map, policy::key::kDnsOverHttpsMode, |
| std::make_unique<base::Value>(chrome_browser_net::kDnsOverHttpsModeOff)); |
| EXPECT_TRUE(GetLastSettingsChangedMessage( |
| &secure_dns_mode, &secure_dns_templates, &management_mode)); |
| EXPECT_EQ(chrome_browser_net::kDnsOverHttpsModeOff, secure_dns_mode); |
| EXPECT_EQ(static_cast<int>( |
| chrome_browser_net::SecureDnsUiManagementMode::kNoOverride), |
| management_mode); |
| } |
| |
| // On platforms where enterprise policies do not have default values, test |
| // that DoH is disabled when non-DoH policies are set. |
| #if !defined(OS_CHROMEOS) |
| IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, OtherPoliciesSet) { |
| policy::PolicyMap policy_map; |
| SetPolicyForPolicyKey(&policy_map, policy::key::kIncognitoModeAvailability, |
| std::make_unique<base::Value>(1)); |
| |
| PrefService* local_state = g_browser_process->local_state(); |
| local_state->SetString(prefs::kDnsOverHttpsMode, |
| chrome_browser_net::kDnsOverHttpsModeSecure); |
| |
| std::string secure_dns_mode; |
| std::vector<std::string> secure_dns_templates; |
| int management_mode; |
| EXPECT_TRUE(GetLastSettingsChangedMessage( |
| &secure_dns_mode, &secure_dns_templates, &management_mode)); |
| EXPECT_EQ(chrome_browser_net::kDnsOverHttpsModeOff, secure_dns_mode); |
| EXPECT_EQ( |
| static_cast<int>( |
| chrome_browser_net::SecureDnsUiManagementMode::kDisabledManaged), |
| management_mode); |
| } |
| #endif |
| |
| // This test makes no assumptions about the country or underlying resolver list. |
| IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, DropdownList) { |
| base::ListValue args; |
| args.AppendString(kWebUiFunctionName); |
| |
| web_ui_.HandleReceivedMessage(kGetSecureDnsResolverList, &args); |
| const content::TestWebUI::CallData& call_data = *web_ui_.call_data().back(); |
| EXPECT_EQ("cr.webUIResponse", call_data.function_name()); |
| EXPECT_EQ(kWebUiFunctionName, call_data.arg1()->GetString()); |
| ASSERT_TRUE(call_data.arg2()->GetBool()); |
| |
| // Check results. |
| base::Value::ConstListView resolver_list = call_data.arg3()->GetList(); |
| ASSERT_GE(resolver_list.size(), 1U); |
| EXPECT_EQ("custom", resolver_list[0].FindKey("value")->GetString()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, DropdownListForCountry) { |
| // The 'EE' list should start with the custom entry, followed by the two |
| // global providers and the 'EE' provider in some random order. |
| base::Value resolver_list = handler_->GetSecureDnsResolverListForCountry( |
| country_codes::CountryCharsToCountryID('E', 'E'), |
| GetDohProviderListForTesting()); |
| EXPECT_EQ(4u, resolver_list.GetList().size()); |
| EXPECT_EQ("custom", resolver_list.GetList()[0].FindKey("value")->GetString()); |
| EXPECT_TRUE(FindDropdownItem(resolver_list, "Global Provider 1", |
| "https://global1.provider/dns-query{?dns}", |
| "https://global1.provider/privacy_policy/")); |
| EXPECT_TRUE(FindDropdownItem(resolver_list, "Global Provider 2", |
| "https://global2.provider/dns-query{?dns}", |
| "https://global2.provider/privacy_policy/")); |
| EXPECT_TRUE(FindDropdownItem(resolver_list, "EE/FR Provider", |
| "https://ee.fr.provider/dns-query{?dns}", |
| "https://ee.fr.provider/privacy_policy/")); |
| |
| // The 'FR' list should start with the custom entry, followed by the two |
| // global providers and the two 'FR' providers in some random order. |
| resolver_list = handler_->GetSecureDnsResolverListForCountry( |
| country_codes::CountryCharsToCountryID('F', 'R'), |
| GetDohProviderListForTesting()); |
| EXPECT_EQ(5u, resolver_list.GetList().size()); |
| EXPECT_EQ("custom", resolver_list.GetList()[0].FindKey("value")->GetString()); |
| EXPECT_TRUE(FindDropdownItem(resolver_list, "Global Provider 1", |
| "https://global1.provider/dns-query{?dns}", |
| "https://global1.provider/privacy_policy/")); |
| EXPECT_TRUE(FindDropdownItem(resolver_list, "Global Provider 2", |
| "https://global2.provider/dns-query{?dns}", |
| "https://global2.provider/privacy_policy/")); |
| EXPECT_TRUE(FindDropdownItem(resolver_list, "EE/FR Provider", |
| "https://ee.fr.provider/dns-query{?dns}", |
| "https://ee.fr.provider/privacy_policy/")); |
| EXPECT_TRUE(FindDropdownItem(resolver_list, "FR Provider", |
| "https://fr.provider/dns-query{?dns}", |
| "https://fr.provider/privacy_policy/")); |
| |
| // The 'CA' list should start with the custom entry, followed by the two |
| // global providers. |
| resolver_list = handler_->GetSecureDnsResolverListForCountry( |
| country_codes::CountryCharsToCountryID('C', 'A'), |
| GetDohProviderListForTesting()); |
| EXPECT_EQ(3u, resolver_list.GetList().size()); |
| EXPECT_EQ("custom", resolver_list.GetList()[0].FindKey("value")->GetString()); |
| EXPECT_TRUE(FindDropdownItem(resolver_list, "Global Provider 1", |
| "https://global1.provider/dns-query{?dns}", |
| "https://global1.provider/privacy_policy/")); |
| EXPECT_TRUE(FindDropdownItem(resolver_list, "Global Provider 2", |
| "https://global2.provider/dns-query{?dns}", |
| "https://global2.provider/privacy_policy/")); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, DropdownListChange) { |
| // Populate the map for recording dropdown change metrics. |
| base::Value resolver_list = handler_->GetSecureDnsResolverListForCountry( |
| country_codes::CountryCharsToCountryID('E', 'E'), |
| GetDohProviderListForTesting()); |
| EXPECT_EQ(4u, resolver_list.GetList().size()); |
| |
| base::HistogramTester histograms; |
| base::ListValue args; |
| args.AppendString("custom" /* old_provider */); |
| args.AppendString( |
| "https://global1.provider/dns-query{?dns}" /* new_provider */); |
| web_ui_.HandleReceivedMessage(kRecordUserDropdownInteraction, &args); |
| |
| const std::string uma_base("Net.DNS.UI.DropdownSelectionEvent"); |
| histograms.ExpectTotalCount(uma_base + ".Ignored", 2u); |
| histograms.ExpectTotalCount(uma_base + ".Selected", 1u); |
| histograms.ExpectTotalCount(uma_base + ".Unselected", 1u); |
| } |
| |
| class SecureDnsHandlerTestWithDisabledProviders : public SecureDnsHandlerTest { |
| protected: |
| SecureDnsHandlerTestWithDisabledProviders() { |
| scoped_features_.InitAndEnableFeatureWithParameters( |
| features::kDnsOverHttps, |
| {{"DisabledProviders", |
| "Provider_Global2, , Provider_EE_FR,Unexpected"}}); |
| } |
| |
| private: |
| base::test::ScopedFeatureList scoped_features_; |
| |
| DISALLOW_COPY_AND_ASSIGN(SecureDnsHandlerTestWithDisabledProviders); |
| }; |
| |
| IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTestWithDisabledProviders, |
| DropdownListDisabledProviders) { |
| // The 'FR' list should start with the custom entry, followed by the two |
| // global providers and the two 'FR' providers in some random order. |
| base::Value resolver_list = handler_->GetSecureDnsResolverListForCountry( |
| country_codes::CountryCharsToCountryID('F', 'R'), |
| GetDohProviderListForTesting()); |
| EXPECT_EQ(3u, resolver_list.GetList().size()); |
| EXPECT_EQ("custom", resolver_list.GetList()[0].FindKey("value")->GetString()); |
| EXPECT_TRUE(FindDropdownItem(resolver_list, "Global Provider 1", |
| "https://global1.provider/dns-query{?dns}", |
| "https://global1.provider/privacy_policy/")); |
| EXPECT_TRUE(FindDropdownItem(resolver_list, "FR Provider", |
| "https://fr.provider/dns-query{?dns}", |
| "https://fr.provider/privacy_policy/")); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTestWithDisabledProviders, |
| SecureDnsTemplates) { |
| std::string good_post_template = "https://foo.test/"; |
| std::string good_get_template = "https://bar.test/dns-query{?dns}"; |
| std::string bad_template = "dns-query{?dns}"; |
| |
| std::string secure_dns_mode; |
| std::vector<std::string> secure_dns_templates; |
| int management_mode; |
| PrefService* local_state = g_browser_process->local_state(); |
| local_state->SetString(prefs::kDnsOverHttpsTemplates, good_post_template); |
| EXPECT_TRUE(GetLastSettingsChangedMessage( |
| &secure_dns_mode, &secure_dns_templates, &management_mode)); |
| EXPECT_EQ(1u, secure_dns_templates.size()); |
| EXPECT_EQ(good_post_template, secure_dns_templates[0]); |
| |
| local_state->SetString(prefs::kDnsOverHttpsTemplates, |
| good_post_template + " " + good_get_template); |
| EXPECT_TRUE(GetLastSettingsChangedMessage( |
| &secure_dns_mode, &secure_dns_templates, &management_mode)); |
| EXPECT_EQ(2u, secure_dns_templates.size()); |
| EXPECT_EQ(good_post_template, secure_dns_templates[0]); |
| EXPECT_EQ(good_get_template, secure_dns_templates[1]); |
| |
| local_state->SetString(prefs::kDnsOverHttpsTemplates, bad_template); |
| EXPECT_TRUE(GetLastSettingsChangedMessage( |
| &secure_dns_mode, &secure_dns_templates, &management_mode)); |
| EXPECT_EQ(0u, secure_dns_templates.size()); |
| |
| local_state->SetString(prefs::kDnsOverHttpsTemplates, |
| bad_template + " " + good_post_template); |
| EXPECT_TRUE(GetLastSettingsChangedMessage( |
| &secure_dns_mode, &secure_dns_templates, &management_mode)); |
| EXPECT_EQ(1u, secure_dns_templates.size()); |
| EXPECT_EQ(good_post_template, secure_dns_templates[0]); |
| |
| // Should still return a provider that was disabled. |
| local_state->SetString(prefs::kDnsOverHttpsTemplates, |
| "https://global2.provider/dns-query{?dns}"); |
| EXPECT_TRUE(GetLastSettingsChangedMessage( |
| &secure_dns_mode, &secure_dns_templates, &management_mode)); |
| EXPECT_EQ(1u, secure_dns_templates.size()); |
| EXPECT_EQ("https://global2.provider/dns-query{?dns}", |
| secure_dns_templates[0]); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, TemplateValid) { |
| base::ListValue args; |
| args.AppendString(kWebUiFunctionName); |
| args.AppendString("https://example.template/dns-query"); |
| |
| base::HistogramTester histograms; |
| web_ui_.HandleReceivedMessage(kValidateCustomDnsEntry, &args); |
| const content::TestWebUI::CallData& call_data = *web_ui_.call_data().back(); |
| EXPECT_EQ("cr.webUIResponse", call_data.function_name()); |
| EXPECT_EQ(kWebUiFunctionName, call_data.arg1()->GetString()); |
| // The request should be successful. |
| ASSERT_TRUE(call_data.arg2()->GetBool()); |
| // The template should be valid. |
| ASSERT_EQ("https://example.template/dns-query", |
| call_data.arg3()->GetString()); |
| histograms.ExpectBucketCount("Net.DNS.UI.ValidationAttemptSuccess", false, 0); |
| histograms.ExpectBucketCount("Net.DNS.UI.ValidationAttemptSuccess", true, 1); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, TemplateInvalid) { |
| base::ListValue args; |
| args.AppendString(kWebUiFunctionName); |
| args.AppendString("invalid_template"); |
| |
| base::HistogramTester histograms; |
| web_ui_.HandleReceivedMessage(kValidateCustomDnsEntry, &args); |
| const content::TestWebUI::CallData& call_data = *web_ui_.call_data().back(); |
| EXPECT_EQ("cr.webUIResponse", call_data.function_name()); |
| EXPECT_EQ(kWebUiFunctionName, call_data.arg1()->GetString()); |
| // The request should be successful. |
| ASSERT_TRUE(call_data.arg2()->GetBool()); |
| // The template should be invalid. |
| ASSERT_EQ(std::string(), call_data.arg3()->GetString()); |
| histograms.ExpectBucketCount("Net.DNS.UI.ValidationAttemptSuccess", false, 1); |
| histograms.ExpectBucketCount("Net.DNS.UI.ValidationAttemptSuccess", true, 0); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, MultipleTemplates) { |
| base::HistogramTester histograms; |
| base::ListValue args_valid; |
| args_valid.AppendString(kWebUiFunctionName); |
| args_valid.AppendString( |
| "invalid_template https://example.template/dns-query"); |
| web_ui_.HandleReceivedMessage(kValidateCustomDnsEntry, &args_valid); |
| const content::TestWebUI::CallData& call_data_valid = |
| *web_ui_.call_data().back(); |
| EXPECT_EQ("cr.webUIResponse", call_data_valid.function_name()); |
| EXPECT_EQ(kWebUiFunctionName, call_data_valid.arg1()->GetString()); |
| // The request should be successful. |
| ASSERT_TRUE(call_data_valid.arg2()->GetBool()); |
| // The second template should be valid. |
| ASSERT_EQ("https://example.template/dns-query", |
| call_data_valid.arg3()->GetString()); |
| histograms.ExpectBucketCount("Net.DNS.UI.ValidationAttemptSuccess", false, 0); |
| histograms.ExpectBucketCount("Net.DNS.UI.ValidationAttemptSuccess", true, 1); |
| |
| base::ListValue args_invalid; |
| args_invalid.AppendString(kWebUiFunctionName); |
| args_invalid.AppendString("invalid_template another_invalid_template"); |
| web_ui_.HandleReceivedMessage(kValidateCustomDnsEntry, &args_invalid); |
| const content::TestWebUI::CallData& call_data_invalid = |
| *web_ui_.call_data().back(); |
| EXPECT_EQ("cr.webUIResponse", call_data_invalid.function_name()); |
| EXPECT_EQ(kWebUiFunctionName, call_data_invalid.arg1()->GetString()); |
| // The request should be successful. |
| ASSERT_TRUE(call_data_invalid.arg2()->GetBool()); |
| // The entry should be invalid. |
| ASSERT_EQ(std::string(), call_data_invalid.arg3()->GetString()); |
| histograms.ExpectBucketCount("Net.DNS.UI.ValidationAttemptSuccess", false, 1); |
| histograms.ExpectBucketCount("Net.DNS.UI.ValidationAttemptSuccess", true, 1); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, TemplateProbeSuccess) { |
| auto network_context_ = |
| std::make_unique<chrome_browser_net::FakeHostResolverNetworkContext>( |
| std::vector<chrome_browser_net::FakeHostResolver::SingleResult>( |
| {chrome_browser_net::FakeHostResolver::SingleResult( |
| net::OK, net::ResolveErrorInfo(net::OK), |
| chrome_browser_net::FakeHostResolver:: |
| kOneAddressResponse)}) /* current_config_result_list */, |
| std::vector<chrome_browser_net::FakeHostResolver:: |
| SingleResult>() /* google_config_result_list */); |
| handler_->SetNetworkContextForTesting(network_context_.get()); |
| base::HistogramTester histograms; |
| base::ListValue args_valid; |
| args_valid.AppendString(kWebUiFunctionName); |
| args_valid.AppendString("https://example.template/dns-query"); |
| web_ui_.HandleReceivedMessage(kProbeCustomDnsTemplate, &args_valid); |
| base::RunLoop().RunUntilIdle(); |
| |
| const content::TestWebUI::CallData& call_data_valid = |
| *web_ui_.call_data().back(); |
| EXPECT_EQ("cr.webUIResponse", call_data_valid.function_name()); |
| EXPECT_EQ(kWebUiFunctionName, call_data_valid.arg1()->GetString()); |
| // The request should be successful. |
| ASSERT_TRUE(call_data_valid.arg2()->GetBool()); |
| // The probe query should have succeeded. |
| ASSERT_TRUE(call_data_valid.arg3()->GetBool()); |
| histograms.ExpectBucketCount("Net.DNS.UI.ProbeAttemptSuccess", false, 0); |
| histograms.ExpectBucketCount("Net.DNS.UI.ProbeAttemptSuccess", true, 1); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, TemplateProbeFailure) { |
| auto network_context_ = |
| std::make_unique<chrome_browser_net::FakeHostResolverNetworkContext>( |
| std::vector<chrome_browser_net::FakeHostResolver::SingleResult>( |
| {chrome_browser_net::FakeHostResolver::SingleResult( |
| net::ERR_NAME_NOT_RESOLVED, |
| net::ResolveErrorInfo(net::ERR_DNS_MALFORMED_RESPONSE), |
| chrome_browser_net::FakeHostResolver:: |
| kNoResponse)}) /* current_config_result_list */, |
| std::vector<chrome_browser_net::FakeHostResolver:: |
| SingleResult>() /* google_config_result_list */); |
| handler_->SetNetworkContextForTesting(network_context_.get()); |
| base::HistogramTester histograms; |
| base::ListValue args_valid; |
| args_valid.AppendString(kWebUiFunctionName); |
| args_valid.AppendString("https://example.template/dns-query"); |
| web_ui_.HandleReceivedMessage(kProbeCustomDnsTemplate, &args_valid); |
| base::RunLoop().RunUntilIdle(); |
| |
| const content::TestWebUI::CallData& call_data_valid = |
| *web_ui_.call_data().back(); |
| EXPECT_EQ("cr.webUIResponse", call_data_valid.function_name()); |
| EXPECT_EQ(kWebUiFunctionName, call_data_valid.arg1()->GetString()); |
| // The request should be successful. |
| ASSERT_TRUE(call_data_valid.arg2()->GetBool()); |
| // The probe query should have failed. |
| ASSERT_FALSE(call_data_valid.arg3()->GetBool()); |
| histograms.ExpectBucketCount("Net.DNS.UI.ProbeAttemptSuccess", false, 1); |
| histograms.ExpectBucketCount("Net.DNS.UI.ProbeAttemptSuccess", true, 0); |
| } |
| |
| } // namespace settings |