| // 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 "net/dns/public/dns_over_https_config.h" |
| |
| #include "base/values.h" |
| #include "net/dns/public/dns_over_https_server_config.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace net { |
| namespace { |
| |
| const DnsOverHttpsServerConfig kServerConfig1 = |
| *DnsOverHttpsServerConfig::FromString("https://example1.test"); |
| const DnsOverHttpsServerConfig kServerConfig2 = |
| *DnsOverHttpsServerConfig::FromString("https://example2.test"); |
| |
| TEST(DnsOverHttpsConfigTest, SingleValue) { |
| DnsOverHttpsConfig config({kServerConfig1}); |
| EXPECT_THAT(config.servers(), testing::ElementsAre(kServerConfig1)); |
| |
| base::Value::List expected_servers; |
| expected_servers.Append(kServerConfig1.ToValue()); |
| base::Value::Dict expected_value; |
| expected_value.Set("servers", std::move(expected_servers)); |
| EXPECT_EQ(expected_value, config.ToValue()); |
| |
| EXPECT_EQ(config, config); |
| } |
| |
| TEST(DnsOverHttpsConfigTest, MultiValue) { |
| std::vector<DnsOverHttpsServerConfig> servers{kServerConfig1, kServerConfig2}; |
| DnsOverHttpsConfig config(servers); |
| EXPECT_EQ(servers, config.servers()); |
| |
| EXPECT_EQ(kServerConfig1.server_template() + "\n" + |
| kServerConfig2.server_template(), |
| config.ToString()); |
| |
| base::Value::List expected_servers; |
| expected_servers.Append(kServerConfig1.ToValue()); |
| expected_servers.Append(kServerConfig2.ToValue()); |
| base::Value::Dict expected_value; |
| expected_value.Set("servers", std::move(expected_servers)); |
| EXPECT_EQ(expected_value, config.ToValue()); |
| |
| EXPECT_EQ(config, config); |
| } |
| |
| TEST(DnsOverHttpsConfigTest, Equal) { |
| DnsOverHttpsConfig a({kServerConfig1}); |
| DnsOverHttpsConfig a2({kServerConfig1}); |
| DnsOverHttpsConfig b({kServerConfig1, kServerConfig2}); |
| DnsOverHttpsConfig b2({kServerConfig1, kServerConfig2}); |
| |
| EXPECT_EQ(a, a2); |
| EXPECT_EQ(b, b2); |
| } |
| |
| TEST(DnsOverHttpsConfigTest, NotEqual) { |
| DnsOverHttpsConfig a({kServerConfig1}); |
| DnsOverHttpsConfig b({kServerConfig2}); |
| DnsOverHttpsConfig c({kServerConfig1, kServerConfig2}); |
| DnsOverHttpsConfig d({kServerConfig2, kServerConfig1}); |
| |
| EXPECT_FALSE(a == b); |
| EXPECT_FALSE(a == c); |
| EXPECT_FALSE(a == d); |
| EXPECT_FALSE(c == d); |
| } |
| |
| TEST(DnsOverHttpsConfigTest, FromStringSingleValue) { |
| auto config = |
| DnsOverHttpsConfig::FromString(kServerConfig1.server_template()); |
| EXPECT_THAT(config, testing::Optional(DnsOverHttpsConfig({kServerConfig1}))); |
| } |
| |
| TEST(DnsOverHttpsConfigTest, FromStringMultiValue) { |
| auto config = |
| DnsOverHttpsConfig::FromString(kServerConfig1.server_template() + "\n" + |
| kServerConfig2.server_template()); |
| EXPECT_THAT( |
| config, |
| testing::Optional(DnsOverHttpsConfig({kServerConfig1, kServerConfig2}))); |
| } |
| |
| TEST(DnsOverHttpsConfigTest, FromStringExtraWhitespace) { |
| auto config = DnsOverHttpsConfig::FromString( |
| " \t" + kServerConfig1.server_template() + " " + |
| kServerConfig2.server_template() + "\n "); |
| EXPECT_THAT( |
| config, |
| testing::Optional(DnsOverHttpsConfig({kServerConfig1, kServerConfig2}))); |
| |
| auto config2 = |
| DnsOverHttpsConfig::FromString(kServerConfig1.server_template() + "\t" + |
| kServerConfig2.server_template()); |
| EXPECT_EQ(config2, config); |
| } |
| |
| TEST(DnsOverHttpsConfigTest, FromStringEmpty) { |
| EXPECT_FALSE(DnsOverHttpsConfig::FromString("")); |
| EXPECT_EQ(DnsOverHttpsConfig(), DnsOverHttpsConfig::FromStringLax("")); |
| } |
| |
| TEST(DnsOverHttpsConfigTest, FromStringAllInvalid) { |
| EXPECT_FALSE(DnsOverHttpsConfig::FromString("foo")); |
| EXPECT_EQ(DnsOverHttpsConfig(), DnsOverHttpsConfig::FromStringLax("foo")); |
| |
| EXPECT_FALSE(DnsOverHttpsConfig::FromString("foo bar")); |
| EXPECT_EQ(DnsOverHttpsConfig(), DnsOverHttpsConfig::FromStringLax("foo bar")); |
| } |
| |
| TEST(DnsOverHttpsConfigTest, FromStringSomeInvalid) { |
| std::string some_invalid = "foo " + kServerConfig1.server_template() + |
| " bar " + kServerConfig2.server_template() + |
| " baz"; |
| EXPECT_FALSE(DnsOverHttpsConfig::FromString(some_invalid)); |
| EXPECT_EQ(DnsOverHttpsConfig({kServerConfig1, kServerConfig2}), |
| DnsOverHttpsConfig::FromStringLax(some_invalid)); |
| } |
| |
| TEST(DnsOverHttpsConfigTest, Json) { |
| auto parsed = DnsOverHttpsConfig::FromString(R"( |
| { |
| "servers": [{ |
| "template": "https://dnsserver.example.net/dns-query{?dns}", |
| "endpoints": [{ |
| "ips": ["192.0.2.1", "2001:db8::1"] |
| }, { |
| "ips": ["192.0.2.2", "2001:db8::2"] |
| }] |
| }] |
| } |
| )"); |
| |
| ASSERT_TRUE(parsed); |
| EXPECT_EQ(1u, parsed->servers().size()); |
| |
| auto parsed2 = DnsOverHttpsConfig::FromString(parsed->ToString()); |
| EXPECT_EQ(parsed, parsed2); |
| } |
| |
| TEST(DnsOverHttpsConfigTest, JsonWithUnknownKey) { |
| auto parsed = DnsOverHttpsConfig::FromString(R"( |
| { |
| "servers": [{ |
| "template": "https://dnsserver.example.net/dns-query{?dns}" |
| }], |
| "unknown key": "value is ignored" |
| } |
| )"); |
| |
| ASSERT_TRUE(parsed); |
| EXPECT_EQ(1u, parsed->servers().size()); |
| |
| auto parsed2 = DnsOverHttpsConfig::FromString(parsed->ToString()); |
| EXPECT_EQ(parsed, parsed2); |
| } |
| |
| TEST(DnsOverHttpsConfigTest, BadJson) { |
| // Not JSON |
| EXPECT_FALSE(DnsOverHttpsConfig::FromString("{")); |
| |
| // No servers |
| EXPECT_FALSE(DnsOverHttpsConfig::FromString("{}")); |
| |
| // Not a Dict |
| EXPECT_FALSE(DnsOverHttpsConfig::FromString("[]")); |
| |
| // Wrong type for "servers" |
| EXPECT_FALSE(DnsOverHttpsConfig::FromString("{\"servers\": 12345}")); |
| |
| // One bad server |
| EXPECT_FALSE(DnsOverHttpsConfig::FromString(R"( |
| { |
| "servers": [{ |
| "template": "https://dnsserver.example.net/dns-query{?dns}", |
| }, { |
| "template": "not a valid template" |
| }] |
| } |
| )")); |
| } |
| |
| TEST(DnsOverHttpsConfigTest, JsonLax) { |
| // Valid JSON is allowed |
| auto parsed = *DnsOverHttpsConfig::FromString(R"( |
| { |
| "servers": [{ |
| "template": "https://dnsserver.example.net/dns-query{?dns}", |
| "endpoints": [{ |
| "ips": ["192.0.2.1", "2001:db8::1"] |
| }, { |
| "ips": ["192.0.2.2", "2001:db8::2"] |
| }] |
| }] |
| } |
| )"); |
| DnsOverHttpsConfig reparsed = |
| DnsOverHttpsConfig::FromStringLax(parsed.ToString()); |
| EXPECT_EQ(parsed, reparsed); |
| |
| // Lax parsing does not accept bad servers in JSON. |
| DnsOverHttpsConfig from_bad = DnsOverHttpsConfig::FromStringLax(R"( |
| { |
| "servers": [{ |
| "template": "https://dnsserver.example.net/dns-query{?dns}", |
| }, { |
| "template": "not a valid template" |
| }] |
| } |
| )"); |
| EXPECT_THAT(from_bad.servers(), testing::IsEmpty()); |
| } |
| |
| } // namespace |
| } // namespace net |