zapretgui/tests/test_custom_dns_settings.py
loop-uh 50f9f695ba
All checks were successful
Zapret source guards / validate (push) Successful in 10s
Свой DNS: отдельная страница вместо окна, сервер можно добавить одной строкой DoH — IP-адреса программа находит и проверяет сама; «Автоматически» стала плиткой, кнопка «Сбросить кэш DNS» больше не прокручивает страницу
Страница «Свой 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>
2026-10-08 00:47:55 +03:00

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()