package option import ( "context" "testing" C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing/common/json" "github.com/sagernet/sing/service" "github.com/stretchr/testify/require" ) type stubDNSTransportOptionsRegistry struct{} func (stubDNSTransportOptionsRegistry) CreateOptions(transportType string) (any, bool) { switch transportType { case C.DNSTypeUDP: return new(RemoteDNSServerOptions), true case C.DNSTypeFakeIP: return new(FakeIPDNSServerOptions), true default: return nil, false } } func TestDNSOptionsRejectsLegacyFakeIPOptions(t *testing.T) { t.Parallel() ctx := service.ContextWith[DNSTransportOptionsRegistry](context.Background(), stubDNSTransportOptionsRegistry{}) var options DNSOptions err := json.UnmarshalContext(ctx, []byte(`{ "fakeip": { "enabled": true, "inet4_range": "198.18.0.0/15" } }`), &options) require.EqualError(t, err, legacyDNSFakeIPRemovedMessage) } func TestDNSServerOptionsRejectsLegacyFormats(t *testing.T) { t.Parallel() ctx := service.ContextWith[DNSTransportOptionsRegistry](context.Background(), stubDNSTransportOptionsRegistry{}) testCases := []string{ `{"address":"1.1.1.1"}`, `{"type":"legacy","address":"1.1.1.1"}`, } for _, content := range testCases { var options DNSServerOptions err := json.UnmarshalContext(ctx, []byte(content), &options) require.EqualError(t, err, legacyDNSServerRemovedMessage) } } func TestDNSOptionsAcceptsTypedServers(t *testing.T) { t.Parallel() ctx := service.ContextWith[DNSTransportOptionsRegistry](context.Background(), stubDNSTransportOptionsRegistry{}) var options DNSOptions err := json.UnmarshalContext(ctx, []byte(`{ "servers": [ {"type": "udp", "tag": "default", "server": "1.1.1.1"}, {"type": "fakeip", "tag": "fake", "inet4_range": "198.18.0.0/15"} ] }`), &options) require.NoError(t, err) require.Len(t, options.Servers, 2) require.Equal(t, C.DNSTypeUDP, options.Servers[0].Type) require.Equal(t, "1.1.1.1", options.Servers[0].Options.(*RemoteDNSServerOptions).Server) require.Equal(t, C.DNSTypeFakeIP, options.Servers[1].Type) }