All checks were successful
Zapret source guards / validate (push) Successful in 10s
Страница «Свой DNS» (dns.ui.custom_server_page) открывается из «Настройки DNS» и показывает путь хлебными крошками. Три поля вместо пяти: адрес DoH, IP-адреса одной строкой (IPv4 и IPv6 вместе) и название, которое можно не писать. Если задан только адрес DoH, программа узнаёт адреса сервера у эталонных серверов по DoH и у DNS системы, а затем проверяет каждый настоящим запросом DoH с проверкой сертификата (dns.doh_lookup). На Windows без DoH адрес должен отвечать и на обычный DNS, иначе сервер не сохраняется. Шаблон DoH своего сервера попадает в настройки адаптера так же, как у серверов программы. Правила своих серверов вынесены из окна в dns.custom_servers; список читается и пишется в фоне одной транзакцией (settings.store.update_custom_dns_servers) и приходит на страницу вместе с её состоянием. Страница DNS обновляет состояние при каждом открытии. Кнопка «Вернуть автоматически» заменена первой плиткой сетки и применяется сразу, без вопроса. Кнопка сброса кэша не выключается на время работы: выключенная теряла фокус, он уходил на сетку плиток, и страница прокручивалась к выбранному серверу. Сетка прокручивает к плитке только при фокусе с клавиатуры. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
83 lines
3 KiB
Python
83 lines
3 KiB
Python
from __future__ import annotations
|
|
|
|
import unittest
|
|
|
|
from dns.custom_servers import CUSTOM_DNS_CATEGORY, build_dns_providers_with_custom
|
|
from settings import schema
|
|
from settings.normalize import normalize_dns
|
|
|
|
|
|
class CustomDnsSettingsTests(unittest.TestCase):
|
|
def test_default_dns_settings_include_empty_custom_servers_list(self) -> None:
|
|
self.assertEqual(schema.default_dns()["custom_servers"], [])
|
|
|
|
def test_custom_dns_settings_are_normalized(self) -> None:
|
|
normalized = normalize_dns(
|
|
{
|
|
"custom_servers": [
|
|
{
|
|
"id": "home",
|
|
"name": " Домашний DNS ",
|
|
"ipv4": ["8.8.8.8", "8.8.8.8", "bad"],
|
|
"ipv6": ["2001:4860:4860::8888"],
|
|
},
|
|
{
|
|
"id": "empty",
|
|
"name": "Пустой",
|
|
"ipv4": [],
|
|
},
|
|
]
|
|
}
|
|
)
|
|
|
|
self.assertEqual(
|
|
normalized["custom_servers"],
|
|
[
|
|
{
|
|
"id": "home",
|
|
"name": "Домашний DNS",
|
|
"ipv4": ["8.8.8.8"],
|
|
"ipv6": ["2001:4860:4860::8888"],
|
|
"doh": "",
|
|
}
|
|
],
|
|
)
|
|
|
|
def test_doh_address_is_kept_only_when_it_is_https(self) -> None:
|
|
def doh_of(value):
|
|
servers = normalize_dns({"custom_servers": [{"id": "a", "name": "A", "ipv4": ["9.9.9.9"], "doh": value}]})
|
|
return servers["custom_servers"][0]["doh"]
|
|
|
|
self.assertEqual(doh_of(" https://dns.example.com/dns-query "), "https://dns.example.com/dns-query")
|
|
self.assertEqual(doh_of("http://dns.example.com/dns-query"), "")
|
|
self.assertEqual(doh_of("https://dns.example.com/dns query"), "")
|
|
self.assertEqual(doh_of(None), "")
|
|
|
|
def test_server_with_doh_but_without_addresses_is_dropped(self) -> None:
|
|
# Windows принимает только IP-адреса: запись без них применить нельзя.
|
|
normalized = normalize_dns(
|
|
{"custom_servers": [{"id": "a", "name": "A", "doh": "https://dns.example.com/dns-query"}]}
|
|
)
|
|
|
|
self.assertEqual(normalized["custom_servers"], [])
|
|
|
|
def test_custom_dns_settings_become_provider_group(self) -> None:
|
|
providers = build_dns_providers_with_custom(
|
|
{"Основные": {"Cloudflare": {"ipv4": ["1.1.1.1"], "ipv6": []}}},
|
|
[
|
|
{
|
|
"id": "home",
|
|
"name": "Домашний DNS",
|
|
"ipv4": ["8.8.8.8"],
|
|
"ipv6": [],
|
|
}
|
|
],
|
|
)
|
|
|
|
self.assertIn(CUSTOM_DNS_CATEGORY, providers)
|
|
self.assertEqual(providers[CUSTOM_DNS_CATEGORY]["Домашний DNS"]["ipv4"], ["8.8.8.8"])
|
|
self.assertIn("Cloudflare", providers["Основные"])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|