Files
xboard-node/internal/model/custom_route_validate_test.go

85 lines
2.8 KiB
Go

package model
import (
"strings"
"testing"
)
func TestValidateCustomRouteRules(t *testing.T) {
available := map[string]struct{}{"direct": {}, "block": {}, "warp": {}, "proxy": {}}
tests := []struct {
name string
rules []CustomRouteRule
kernel string
wantErr string
}{
{
name: "valid route target",
rules: []CustomRouteRule{{
Match: RouteMatch{DomainSuffixes: []string{"example.com"}, Ports: []string{"443"}, Networks: []string{"tcp"}},
Action: RouteAction{Type: "route", Target: "warp"},
}},
kernel: "singbox",
},
{
name: "missing match",
rules: []CustomRouteRule{{Action: RouteAction{Type: "direct"}}},
kernel: "singbox",
wantErr: "custom_route_rules[0].match is required",
},
{
name: "unknown target",
rules: []CustomRouteRule{{Match: RouteMatch{DomainSuffixes: []string{"example.com"}}, Action: RouteAction{Type: "route", Target: "missing"}}},
kernel: "singbox",
wantErr: `custom_route_rules[0].action.target references unknown outbound "missing"`,
},
{
name: "route target required",
rules: []CustomRouteRule{{Match: RouteMatch{DomainSuffixes: []string{"example.com"}}, Action: RouteAction{Type: "route"}}},
kernel: "singbox",
wantErr: "custom_route_rules[0].action.target is required when action.type is route",
},
{
name: "direct target forbidden",
rules: []CustomRouteRule{{Match: RouteMatch{DomainSuffixes: []string{"example.com"}}, Action: RouteAction{Type: "direct", Target: "warp"}}},
kernel: "singbox",
wantErr: "custom_route_rules[0].action.target is only allowed when action.type is route",
},
{
name: "unsupported action",
rules: []CustomRouteRule{{Match: RouteMatch{DomainSuffixes: []string{"example.com"}}, Action: RouteAction{Type: "dns"}}},
kernel: "singbox",
wantErr: `custom_route_rules[0].action.type "dns" is not supported by kernel "singbox"`,
},
{
name: "invalid port range",
rules: []CustomRouteRule{{Match: RouteMatch{Ports: []string{"2000-1000"}}, Action: RouteAction{Type: "direct"}}},
kernel: "singbox",
wantErr: `custom_route_rules[0].match.ports contains invalid port range "2000-1000"`,
},
{
name: "invalid network",
rules: []CustomRouteRule{{Match: RouteMatch{Networks: []string{"icmp"}}, Action: RouteAction{Type: "direct"}}},
kernel: "singbox",
wantErr: `custom_route_rules[0].match.networks contains unsupported network "icmp"`,
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
err := ValidateCustomRouteRules(tc.rules, tc.kernel, available)
if tc.wantErr == "" && err != nil {
t.Fatalf("expected no error, got %v", err)
}
if tc.wantErr != "" {
if err == nil {
t.Fatal("expected error, got nil")
}
if !strings.Contains(err.Error(), tc.wantErr) {
t.Fatalf("unexpected error: %v", err)
}
}
})
}
}