mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-10-26 17:41:33 +08:00
- Add `CatalogSources` configuration to allow overriding general, Codex, and Devin catalog sources via URLs or absolute local file paths - Centralize model catalog fetch, validation, and scheduled background updates in `catalogUpdater` - Support dynamic catalog source updates and hot reloading during service runtime - Update `--local-model` flag to use embedded models as defaults while respecting explicit overrides Closes: #6319 Closes: #5024
223 lines
5.5 KiB
Go
223 lines
5.5 KiB
Go
package main
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/router-for-me/CLIProxyAPI/v8/internal/config"
|
|
)
|
|
|
|
func TestArgvEnablesBoolFlag(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
args []string
|
|
flag string
|
|
want bool
|
|
}{
|
|
{name: "bare long flag", args: []string{"--discover-json"}, flag: "discover-json", want: true},
|
|
{name: "assigned true", args: []string{"--discover-json=true"}, flag: "discover-json", want: true},
|
|
{name: "assigned false", args: []string{"--discover-json=false"}, flag: "discover-json", want: false},
|
|
{name: "does not match timeout", args: []string{"--discover-timeout", "3"}, flag: "discover", want: false},
|
|
{name: "bare discover", args: []string{"--discover"}, flag: "discover", want: true},
|
|
{name: "stops at terminator", args: []string{"--", "--discover-json"}, flag: "discover-json", want: false},
|
|
{name: "stops at non-flag", args: []string{"foo", "--discover-json"}, flag: "discover-json", want: false},
|
|
{name: "skips config value", args: []string{"--config", "config.yaml", "--discover-json"}, flag: "discover-json", want: true},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := argvEnablesBoolFlag(tt.args, tt.flag); got != tt.want {
|
|
t.Fatalf("argvEnablesBoolFlag(%v, %q) = %t, want %t", tt.args, tt.flag, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestShouldEnableExampleAPIKeySafeMode(t *testing.T) {
|
|
cfgWithExampleKey := &config.Config{
|
|
SDKConfig: config.SDKConfig{
|
|
APIKeys: []string{"real-key", " your-api-key-1 "},
|
|
},
|
|
}
|
|
cfgWithRealKey := &config.Config{
|
|
SDKConfig: config.SDKConfig{
|
|
APIKeys: []string{"real-key"},
|
|
},
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
cfg *config.Config
|
|
commandMode bool
|
|
tuiMode bool
|
|
standalone bool
|
|
cloudConfigMissing bool
|
|
homeMode bool
|
|
want bool
|
|
}{
|
|
{
|
|
name: "normal server with example key",
|
|
cfg: cfgWithExampleKey,
|
|
want: true,
|
|
},
|
|
{
|
|
name: "standalone tui with example key",
|
|
cfg: cfgWithExampleKey,
|
|
tuiMode: true,
|
|
standalone: true,
|
|
want: true,
|
|
},
|
|
{
|
|
name: "pure tui client is not blocked",
|
|
cfg: cfgWithExampleKey,
|
|
tuiMode: true,
|
|
standalone: false,
|
|
commandMode: false,
|
|
want: false,
|
|
},
|
|
{
|
|
name: "one-shot command is not blocked",
|
|
cfg: cfgWithExampleKey,
|
|
commandMode: true,
|
|
want: false,
|
|
},
|
|
{
|
|
name: "home mode is not blocked",
|
|
cfg: cfgWithExampleKey,
|
|
homeMode: true,
|
|
want: false,
|
|
},
|
|
{
|
|
name: "cloud standby without config is not blocked",
|
|
cfg: cfgWithExampleKey,
|
|
cloudConfigMissing: true,
|
|
want: false,
|
|
},
|
|
{
|
|
name: "normal server with real key",
|
|
cfg: cfgWithRealKey,
|
|
want: false,
|
|
},
|
|
{
|
|
name: "nil config",
|
|
cfg: nil,
|
|
want: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := shouldEnableExampleAPIKeySafeMode(tt.cfg, tt.commandMode, tt.tuiMode, tt.standalone, tt.cloudConfigMissing, tt.homeMode)
|
|
if got != tt.want {
|
|
t.Fatalf("shouldEnableExampleAPIKeySafeMode() = %t, want %t", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHomeConfigPayloadPortApplication(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
yamlBody string
|
|
wantPort int
|
|
}{
|
|
{
|
|
name: "custom port honored",
|
|
yamlBody: "port: 9090\n",
|
|
wantPort: 9090,
|
|
},
|
|
{
|
|
name: "custom port 8327 honored",
|
|
yamlBody: "port: 8327\n",
|
|
wantPort: 8327,
|
|
},
|
|
{
|
|
name: "missing port defaults to 8317",
|
|
yamlBody: "debug: true\n",
|
|
wantPort: 8317,
|
|
},
|
|
{
|
|
name: "standard port 8317 preserved",
|
|
yamlBody: "port: 8317\n",
|
|
wantPort: 8317,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
parsed, errParse := config.ParseConfigBytes([]byte(tt.yamlBody))
|
|
if errParse != nil {
|
|
t.Fatalf("ParseConfigBytes() error = %v", errParse)
|
|
}
|
|
if parsed == nil {
|
|
parsed = &config.Config{}
|
|
}
|
|
parsed.Port = config.NormalizeHomePort(parsed.Port)
|
|
if parsed.Port != tt.wantPort {
|
|
t.Fatalf("parsed.Port = %d, want %d", parsed.Port, tt.wantPort)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestResolveManagementBaseURL(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
flagURL string
|
|
cfg *config.Config
|
|
want string
|
|
}{
|
|
{
|
|
name: "flag takes highest precedence",
|
|
flagURL: "https://flag.example.com",
|
|
cfg: &config.Config{
|
|
RemoteManagement: config.RemoteManagement{
|
|
BaseURL: "https://cfg.example.com",
|
|
},
|
|
Port: 9000,
|
|
},
|
|
want: "https://flag.example.com",
|
|
},
|
|
{
|
|
name: "config base url used when flag is empty",
|
|
flagURL: "",
|
|
cfg: &config.Config{
|
|
RemoteManagement: config.RemoteManagement{
|
|
BaseURL: "https://cfg.example.com",
|
|
},
|
|
Port: 9000,
|
|
},
|
|
want: "https://cfg.example.com",
|
|
},
|
|
{
|
|
name: "config port used when neither flag nor base url provided",
|
|
flagURL: "",
|
|
cfg: &config.Config{
|
|
Port: 9090,
|
|
},
|
|
want: "http://127.0.0.1:9090",
|
|
},
|
|
{
|
|
name: "nil config falls back to default port 8317",
|
|
flagURL: "",
|
|
cfg: nil,
|
|
want: "http://127.0.0.1:8317",
|
|
},
|
|
{
|
|
name: "zero port falls back to default port 8317",
|
|
flagURL: "",
|
|
cfg: &config.Config{
|
|
Port: 0,
|
|
},
|
|
want: "http://127.0.0.1:8317",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := resolveManagementBaseURL(tt.flagURL, tt.cfg)
|
|
if got != tt.want {
|
|
t.Fatalf("resolveManagementBaseURL(%q, %v) = %q, want %q", tt.flagURL, tt.cfg, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|