package xboard import ( "testing" "github.com/sagernet/sing-box/option" ) func TestXUserResolveKeyPrefersPasswordFields(t *testing.T) { user := XUser{ UUID: "uuid-value", Passwd: "passwd-value", Password: "password-value", Token: "token-value", } if got := user.ResolveKey(); got != "passwd-value" { t.Fatalf("ResolveKey() = %q, want %q", got, "passwd-value") } } func TestXUserIdentifierPrefersUUID(t *testing.T) { user := XUser{ ID: 7, UUID: "uuid-value", Email: "user@example.com", } if got := user.Identifier(); got != "uuid-value" { t.Fatalf("Identifier() = %q, want %q", got, "uuid-value") } } func TestResolveUserKeyForSS2022CombinedPassword(t *testing.T) { service := &Service{ssServerKey: "master-key"} user := XUser{ ID: 1, Password: "master-key:user-key", UUID: "uuid-value", } if got := service.resolveUserKey(user, true); got != "user-key" { t.Fatalf("resolveUserKey() = %q, want %q", got, "user-key") } } func TestResolveUserKeyForNonSS2022UsesResolvedKey(t *testing.T) { service := &Service{} user := XUser{ UUID: "uuid-value", Passwd: "passwd-value", } if got := service.resolveUserKey(user, false); got != "passwd-value" { t.Fatalf("resolveUserKey() = %q, want %q", got, "passwd-value") } } func TestXUserIdentifierFallsBackToEmailThenID(t *testing.T) { userWithEmail := XUser{ ID: 8, Email: "user@example.com", } if got := userWithEmail.Identifier(); got != "user@example.com" { t.Fatalf("Identifier() = %q, want %q", got, "user@example.com") } userWithID := XUser{ID: 9} if got := userWithID.Identifier(); got != "9" { t.Fatalf("Identifier() = %q, want %q", got, "9") } } func TestExpandNodeOptions(t *testing.T) { base := option.XBoardServiceOptions{ PanelURL: "https://panel.example", Key: "shared-token", NodeType: "vless", Nodes: []option.XBoardNodeOptions{ {NodeID: 1}, {NodeID: 2, NodeType: "anytls"}, }, } nodes := expandNodeOptions(base) if len(nodes) != 2 { t.Fatalf("expandNodeOptions() len = %d, want 2", len(nodes)) } if nodes[0].NodeID != 1 || nodes[0].NodeType != "vless" { t.Fatalf("first node = %+v", nodes[0]) } if nodes[1].NodeID != 2 || nodes[1].NodeType != "anytls" { t.Fatalf("second node = %+v", nodes[1]) } } func TestBuildInboundMultiplex(t *testing.T) { config := &XMultiplexConfig{ Enabled: true, Padding: true, Brutal: &XBrutalConfig{ Enabled: true, UpMbps: 100, DownMbps: 200, }, } got := buildInboundMultiplex(config) if got == nil { t.Fatal("buildInboundMultiplex() returned nil") } if !got.Enabled || !got.Padding { t.Fatalf("buildInboundMultiplex() = %+v", got) } if got.Brutal == nil || !got.Brutal.Enabled || got.Brutal.UpMbps != 100 || got.Brutal.DownMbps != 200 { t.Fatalf("buildInboundMultiplex() brutal = %+v", got.Brutal) } } func TestNormalizePanelNodeType(t *testing.T) { tests := map[string]string{ "v2ray": "vmess", "hysteria2": "hysteria", "vless": "vless", "": "", } for input, want := range tests { if got := normalizePanelNodeType(input); got != want { t.Fatalf("normalizePanelNodeType(%q) = %q, want %q", input, got, want) } } }