package config import ( "os" "path/filepath" "testing" ) func TestLoadAndApplyDefaults(t *testing.T) { dir := t.TempDir() path := filepath.Join(dir, "cfg.yaml") content := ` listen: 127.0.0.1:9999 gateway_keys: [sk-1] default_model: AUTO adapter_dir: adapters runtime_file: runtime.json sources: - name: deepseek base_url: https://api.deepseek.com api_key: sk-d adapter: deepseek models: - id: deepseek-v4-flash priority: 100 - name: ollama base_url: http://127.0.0.1:11434 adapter: ollama endpoint: /api/chat models: - id: llama3 priority: 50 ` if err := os.WriteFile(path, []byte(content), 0644); err != nil { t.Fatal(err) } cfg, err := Load(path) if err != nil { t.Fatalf("load: %v", err) } if len(cfg.Sources) != 2 { t.Fatalf("sources = %d", len(cfg.Sources)) } if cfg.Sources[1].Endpoint != "/api/chat" { t.Fatalf("endpoint = %q", cfg.Sources[1].Endpoint) } if cfg.Sources[1].Timeout == 0 { t.Fatal("default timeout not applied") } if cfg.Sources[1].MaxConcurrent == 0 { t.Fatal("default max_concurrent not applied") } if cfg.Sources[0].Models[0].Priority != 100 { t.Fatalf("priority = %d", cfg.Sources[0].Models[0].Priority) } if cfg.DefaultModel != "AUTO" { t.Fatalf("default model = %q", cfg.DefaultModel) } } func TestApplyDefaultsDuplicateSource(t *testing.T) { cfg := Config{Sources: []Source{ {Name: "a", BaseURL: "http://x", Models: []Model{{ID: "m1"}}}, {Name: "a", BaseURL: "http://y", Models: []Model{{ID: "m2"}}}, }} if err := cfg.ApplyDefaults(); err == nil { t.Fatal("expected duplicate source error") } } func TestApplyDefaultsNoSources(t *testing.T) { // empty source list is valid (sources may be added later via the Web UI) cfg := Config{} if err := cfg.ApplyDefaults(); err != nil { t.Fatal(err) } if cfg.Listen != ":8080" || cfg.DefaultModel != "AUTO" { t.Fatalf("defaults not applied: %+v", cfg) } } func TestApplyDefaultsDuplicateModel(t *testing.T) { cfg := Config{Sources: []Source{ {Name: "a", BaseURL: "http://x", Models: []Model{{ID: "m1"}}}, {Name: "b", BaseURL: "http://y", Models: []Model{{ID: "m1"}}}, }} if err := cfg.ApplyDefaults(); err == nil { t.Fatal("expected duplicate model error") } } func TestStoreUpsertRemove(t *testing.T) { path := filepath.Join(t.TempDir(), "runtime.json") s := NewStore(path) if err := s.Load(); err != nil { t.Fatal(err) } if err := s.Upsert(Source{Name: "a", BaseURL: "http://a", Models: []Model{{ID: "m"}}}); err != nil { t.Fatal(err) } if err := s.Upsert(Source{Name: "b", BaseURL: "http://b", Models: []Model{{ID: "m2"}}}); err != nil { t.Fatal(err) } if len(s.List()) != 2 { t.Fatalf("list = %d", len(s.List())) } removed, err := s.Remove("a") if err != nil || !removed { t.Fatalf("remove: %v %v", removed, err) } if len(s.List()) != 1 { t.Fatalf("after remove list = %d", len(s.List())) } // reload from disk s2 := NewStore(path) if err := s2.Load(); err != nil { t.Fatal(err) } if len(s2.List()) != 1 { t.Fatalf("reloaded list = %d", len(s2.List())) } }