ci / check (push) Successful in 23m54s
- UI: settings tab with sections (server, API keys, Prometheus, audit, migrate, about); server settings moved there; master keys table rework (menu, chips, version, compact phone cards); three-state node version chip - I1: random per-server template (DNS / QUIC Initial / STUN) kept in users.db, GET/POST /api/masking, change from the master keys banner - Hub rejects nodes older than 0.5.0 (close 4026), /ui/nodes reports outdated - install.sh: spinner for long commands (full output in the log), step progress bar, cards; installs older than 0.5.0 require a full reinstall with data reset - Bump to Beta 0.5.0
59 lines
1.6 KiB
Go
59 lines
1.6 KiB
Go
package ctrl
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestGenI1Templates(t *testing.T) {
|
|
seen := map[string]bool{}
|
|
for i := 0; i < 500; i++ {
|
|
v := GenI1()
|
|
b, ok := i1Bytes(v)
|
|
if !ok {
|
|
t.Fatalf("шаблон не разбирается: %q", v)
|
|
}
|
|
kind, label := DescribeI1(v)
|
|
seen[kind] = true
|
|
switch kind {
|
|
case "dns":
|
|
if !strings.HasPrefix(v, "<r 2>") || !strings.HasPrefix(label, "DNS-запрос к ") {
|
|
t.Fatalf("DNS: %q → %q", v, label)
|
|
}
|
|
case "quic":
|
|
if n := len(b); n != 1200 && n != 1250 && n != 1252 {
|
|
t.Fatalf("QUIC длиной %d: %q", n, v)
|
|
}
|
|
case "stun":
|
|
if len(b) != 20 && len(b) != 28 {
|
|
t.Fatalf("STUN длиной %d: %q", len(b), v)
|
|
}
|
|
default:
|
|
t.Fatalf("неожиданный вид %q: %q", kind, v)
|
|
}
|
|
// Только <b>/<r>, без пробелов вне тегов — так I1 пишут и клиенты AmneziaVPN.
|
|
if strings.Contains(strings.NewReplacer("<b ", "", "<r ", "").Replace(v), " ") {
|
|
t.Fatalf("лишние пробелы: %q", v)
|
|
}
|
|
}
|
|
for _, k := range []string{"dns", "quic", "stun"} {
|
|
if !seen[k] {
|
|
t.Fatalf("шаблон %s ни разу не выпал", k)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestDescribeI1(t *testing.T) {
|
|
cases := map[string]string{
|
|
DefaultParams().I1: "DNS-ответ от icloud.com",
|
|
"": "без маскировки",
|
|
"<c><t>": "свой шаблон",
|
|
"<b 0xdeadbeef>": "свой шаблон",
|
|
}
|
|
for in, want := range cases {
|
|
if _, got := DescribeI1(in); got != want {
|
|
t.Errorf("DescribeI1(%q) = %q, want %q", in, got, want)
|
|
}
|
|
}
|
|
}
|